记Redis在项目中一个类分时图应用场景设计

需求: 项目有一个保存实时抓拍图片的功能,需要统计摄像头下每个时间点(比如一分钟)保存的图片个数,并通过线型图显示到页面上.

这很类似股票的分时K线图的功能.所以我参考了一些网上的文章,采用
Redis来实现这个功能.

先交代一下项目里数据的一个情况:

  1. 摄像头个数在150个左右,单个摄像头每秒抓拍图片数平均在5张左右,150个摄像头一分钟最大抓拍图片量在200左右.
  2. 每天抓拍的图片总数一般在60w-100w, 峰值不超过300w.
  3. 每张图片的大小在8K左右.

需求分析:

  1. 可以显示某个摄像头下每分钟的抓拍图片个数. (时间点:分钟,数值:图片个数)
  2. 显示最近一天的分时图. (分时图的区间:24小时,一天的时间点个数60*24=1440)
  3. 缓存最近一天内的保存图片信息,以最大300w条记录算. (memory< 1K*3000000 约等于3GB, 实际情况不到2G)

接下来重点说一下这里的设计:

  1. 由于每秒中的图片数量不大,不用太考虑读写的压力问题,所以我每接收到一张图,则存入数据库,再写入redis当中.
  2. 存入redis的数据首先用到了redis中的自增操作, redis中分时数据的存储格式为hash结构,key为count+ip,fieldyyyy-MM-dd HH:mm的分钟时间点,value则为图片个数.比如192.168.0.1这个ip的摄像头每抓拍到一张图,则redis 操作命令为 HINCRBY 'count:192.168.0.1' '2018-08-10 10:30' 1 . 当然,这里会做一个定时任务,每分钟都会初始化每个摄像头当前时间点抓拍图片个数为0,操作指令为HSETNX 'count:192.168.0.1' '2018-08-10 10:30' 0,防止查询时找不到对应时刻的数据.由于hash是不支持直接传入过期时间的,所以也需要在定时任务里删除掉24小时之前的数据:HDEL 'count:192.168.0.1' '2018-08-09 10:30'.
  3. 除了自增1操作外,还用到了zset结构,保存图片信息数据. 这里 zsetkeyinfo:+ip,value为图片信息的json数据,如图片的地址,特征id,id等,score则保存的时当前距计算机元年的秒数.之所以这样设计是为了方便重新统计和排序.
  4. 前端显示数据,采用echart库的Line,通过大量数据渲染线型图.主要数据在两个数组,x轴的时间点,y轴的图片个数.两个数组,时间点和个数一一对应.这也是第2步中要做定时任务初始化的原因.
  5. 初次获取摄像头的时分图统计的时候,首先会读取hash结构中对应key的数据,里面存储了最近24小时的统计数据,通过new一个TreeMap可以对时间进行排序,然后mao的key和value就是x,y轴所需的两个数组.获取完成后,每分钟去轮询一次查询当前摄像头,上一分钟的数据,这样能保证数据和时间点一致.
  6. 如果需要获取最近抓拍的图片地址信息等,则可以通过zset结构里的ZRANGEBYSCORE命令查询所需时间段的图片信息.也可以重新统计每个时间点的图片个数.同时这里也要在第2步的定时任务里做一个ZREMRANGEBYSCORE操作移除24小时前的数据.

到这里整个设计思路就展示差不多就基本完成了.当然这不是全部,还有些细节,比如定时任务是否正常执行,数据持久化,服务down掉了怎么处理等.

有时间把一些设计思路的代码写出来.

    原文作者:cchenggit
    原文地址: https://segmentfault.com/a/1190000016083334
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞