redis-缓存设计-记录前一个小时和最新的日志
Posted 意犹未尽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis-缓存设计-记录前一个小时和最新的日志相关的知识,希望对你有一定的参考价值。
需求
记录最新的日志 99条
同时记录上一个小时和最近一个小时的 日志出现次数
记录日志代码
/** * * @param conn 连接 * @param name 模块名字 * @param message 日志信息 * @param level 日志等级 * @param timeout 重试时间 */ public static void logCommon( Jedis conn, String name, String message, String level, int timeout,Date date) { //日志出现数量的key String commonDest = "common:" + name + ‘:‘ + level; //记录当前所处小时数 String startKey = commonDest + ":start"; //上一次所属小时数 String pstartkey= commonDest + ":pstart"; //计算重试后时间 long end = System.currentTimeMillis() + timeout; //获得当前所处小时数 String existing = conn.get(startKey); //yyyy-mm-dd HH:00:00 String hourStart = ISO_FORMAT.format(date); //是否需要重试 while (System.currentTimeMillis() < end) { //对当前所处小时数进行监视 避免其他地方在下一小时切换 比如多线程调用 conn.watch(startKey); Transaction trans = conn.multi(); //表示第一次运行 进行初始化 if (existing == null) { //保存当前最新小时数 trans.set(startKey, hourStart); existing=hourStart; } //如果是下一个小时了 将原来的日志的key重新命名 if (existing != null && COLLATOR.compare(existing, hourStart) < 0) { //通过重命名记录当前记录的key 归档到上一个小时 trans.rename(commonDest, pstartkey); //记录最新的小时数 trans.set(startKey, hourStart); } //记录日志出现次数 对日志出现数进行+1 这里只是记录日志出现次数 trans.zincrby("common:" + name + ‘:‘ + level,1,message); //存储日志 String recentDest = "recent:" + name + ‘:‘ + level; //消息追加到队列 trans.lpush(recentDest, message); //只保留0-99条 trans.ltrim(recentDest, 0, 99); List<Object> results = trans.exec(); // null response indicates that the transaction was aborted due to // the watched key changing. if (results == null) { continue; } return; } }
返回上一次或者下一次日志
/** * 打印日志信息 * @param conn 连接 * @param type top为上一次 current为当前 */ public static void printLog(Jedis conn,String name, String level,String type){ String hourStart=null; String commonDest = "common:" + name + ‘:‘ + level; if(type=="top"){ commonDest=commonDest+":pstart"; } Set<Tuple> common = conn.zrevrangeWithScores(commonDest, 0, -1); for (Tuple tuple : common) { System.out.println("消息: " + tuple.getElement() + ",出现次数 " + tuple.getScore()); } }
测试
public static final Collator COLLATOR = Collator.getInstance(); /** * 用于比较是否是上一小时了 */ public static final SimpleDateFormat TIMESTAMP = new SimpleDateFormat("EEE MMM dd HH:00:00 yyyy"); /** * 用于格式化为yyyy-MM-dd hh:00:00 */ private static final SimpleDateFormat ISO_FORMAT = new SimpleDateFormat("yyyy-MM-dd‘T‘HH:00:00"); static { ISO_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); } public static void main(String[] args) throws Exception { Jedis conn = new Jedis("127.0.0.1", 6379); conn.flushDB(); //录入100条日志信息 for(int i=0;i<10;i++){ logCommon(conn,"促销","前一个小时测试嗷嗷"+i,"info",2000,new Date()); } //模拟切换到下一小时i Calendar calendar=Calendar.getInstance(); calendar.setTime(new Date()); //追加一个小时 calendar.add(Calendar.HOUR,1); for(int i=0;i<3;i++){ logCommon(conn,"促销","当前一个小时测试嗷嗷"+i,"info",2000,calendar.getTime()); //测试重复消息 logCommon(conn,"促销","我是重复数据"+i,"info",2000,calendar.getTime()); // logCommon(conn,"促销","我是重复数据"+i,"info",2000,calendar.getTime()); } //===================获得前一个小时的日志信息==================== System.out.println("获得前一个小时的日志信息"); printLog(conn,"促销","info","top"); //===================获取当前的日志新==================== System.out.println("获得当前最新的日志信息"); printLog(conn,"促销","info","current"); }
打印
得前一个小时的日志信息 消息: 前一个小时测试嗷嗷9,出现次数 1.0 消息: 前一个小时测试嗷嗷8,出现次数 1.0 消息: 前一个小时测试嗷嗷7,出现次数 1.0 消息: 前一个小时测试嗷嗷6,出现次数 1.0 消息: 前一个小时测试嗷嗷5,出现次数 1.0 消息: 前一个小时测试嗷嗷4,出现次数 1.0 消息: 前一个小时测试嗷嗷3,出现次数 1.0 消息: 前一个小时测试嗷嗷2,出现次数 1.0 消息: 前一个小时测试嗷嗷1,出现次数 1.0 消息: 前一个小时测试嗷嗷0,出现次数 1.0 获得当前最新的日志信息 消息: 我是重复数据2,出现次数 2.0 消息: 我是重复数据1,出现次数 2.0 消息: 我是重复数据0,出现次数 2.0 消息: 当前一个小时测试嗷嗷2,出现次数 1.0 消息: 当前一个小时测试嗷嗷1,出现次数 1.0 消息: 当前一个小时测试嗷嗷0,出现次数 1.0
以上是关于redis-缓存设计-记录前一个小时和最新的日志的主要内容,如果未能解决你的问题,请参考以下文章