Redis存储带时间戳分类实时数据问题求教
一个物联网项目,最初选用了Linux + Twisted + MySQL + Python来构建。看重的是Twisted的扩展性。但是MySQL成为性能瓶颈。
系统架构是:
大量设备每隔0.5秒以TCP长连接方式连接Twisted Socket服务器,将实时收集的数据导入数据库中,然后Web浏览器以每隔2秒的间隔从数据库中获取数据并绘图。
数据在MySQL中以二维表形式存在:
recID,devID,timestamp(UNIX), value_1, value_2, .... value_8
由于这些数据均带时间戳,所以读取时,首先要针对特定设备ID进行时间戳对比。实际上是两个需求:检索devID,带时间排序的数值。
在单一表格中由于前段累计数据过快,所以检索时间较长,大约超过3~5秒。
弥补方式一:是定时将Expire的数据删除,但是这在InnoDB引擎中会照成长达45秒的表锁。
弥补方式二:采用PINGPONG方式在不同表间切换,但是这会造成Socket/Web两端数据同步问题,而且表锁依然存在。
有人推荐Memcached和Message Queue来解决问题。一番折腾,发现Redis可以覆盖这两种组件。
但是现在纠结应该使用哪种数据类型存储?String, Hash, List, Set, Sorted Set?
这里面关键在于key检索是需要精确的(hh:mm:ss:ms),而目前浏览器给出的时间不够精确,给出的是时间窗(hh:mm:ss~hh:mm:ss)。直接按照Key检索可能会有遗漏。即使按照通配符检索,会出现整点遗漏的问题。
String类型有Expire,适合做queue,但是如何判断devID?
key=devId:timestamp, value=value1~8?, expire=2s
此外,Redis可以有Pub/Sub模式,不知道应该如何将实时数据设计成这种模式?
4月份提的问题,中间插入一个项目,9月份来重新实施。在实际Coding过程中。发现使用Sorted Set还是有问题。
需求
一批设备每隔0.5秒发送带时间戳的数据给DB,Web端每隔2秒从DB读取后将带时间戳数据集以JSON格式交给绘图JS引擎。
Sorted Set 默认支持排序,可比较删除,可比较读取。按照您提议的数据结构是:
Zset name: DeviceID,如"NOKIA5110"
Zset member: Timestamp, 如20150908 1230 -> "1441687256.437"
Zset value: "0x01,0x02,...... "
Zset score: Timestamp, 以时间戳排序
索引:可以根据NOKIA5110设备号查到该设备下的任意缓存时间戳数据
比较读取:可以根据特定设备号和时间戳score排序比较
删除:必须按照特定设备号进行时间戳score排序删除
但是却必须利用另外的线程(CRON)去实现定期比较删除。Redis Expire 只针对Key,也就是说Sorted Set中的member是无法实现Expire自动删除的。
如果不采用独立线程对member进行比较删除,那么Sorted Set会很快导致系统崩溃。而且一旦设备数量上升,对于CRON和redis压力非常大。
看到这里的讨论:redis里能不能针对set数据的每个member设置过期时间?
看样子,如果要利用Expire指令的话,Sort需要要应用层实施了。
新的思路
采用Redis原始String数据结构
Key Namespace:DeviceId:Timestamp
Key Expiration: 2.1 seconds
Value: Serialized 8Byte data
操作
可删除:自动超时删除数据,无需单独线程
可索引:读取特定设备数据(超时删除后,每组设备为0~5组数据)
易失性:已满足
精确性:时间管理
扩展性:规模可控
排序性:返回集合规模小,5个Key比较实施起来很简单
Python的List结构的Sort可以很快速的解决排序的问题。
所以,由于Redis中排序和定时不可得兼,我放弃了排序这个要求,改在应用层中完成。
定时将Expire的数据删除,这个时间是多久?
Sorted Set,带有排序、定期删除、比较删除,你用Sorted Set实现应该就可以了,主要是你提到timestamp不够精确,你可以自己为它添加年月日吗?
命令可以看http://redisdoc.com/sorted_set/zadd.html
Sorted Set的结构可以这么设计
key score(日期时间索引值) value
devID timestamp的long数值
我讲一个例子出来,有一批设备,几分种就要上报一些值,那么用Sorted Set,key就是设备id,score用日期的数值形态,value就是上报的值,它支持设置数据的过期时间,还支持你给日期删除这之前的所有数据,自带排序
不过对于你的case可能有2个问题点
1.timestamp如果只是时分秒,而过期的数据是以天为单位的话,就会造成重复的score,这样数据就脏了,所以需要一个完整的日期时间
2.Sorted Set有个小缺点,就是vlaue不能重复!
还有个问题就是你确定更换redis后的硬件可以支持吗?redis可是内存数据库,不要指望它的持久化到硬盘,哪怕你重启了,它每次也会在启动时把数据load到内存里
玩蛇网文章,转载请注明出处和文章网址:https://www.iplaypy.com/wenda/wd18861.html
相关文章 Recommend
- • Python操作Redis数据库方面的问题
- • 用python获取带图片的验证码怎么样
- • Python Flask中分散存储大量视频函数的方法
- • flask web开发中使用redis做缓存怎么和数据库同步?
- • 页面带链接目录的问题py sphinx
- • 如何获取TED带字幕的视频下载url
- • redis初始化中参数的作用
- • 求模拟多个client对网络带宽进行竞争的思路
- • Flask sqlalchemy数据未存储到数据库中的原因
- • celery异步任务队列有什么办法使带副作用的函数
- • Python文件存储服务器IOError: [Errno 32] Broken pipe错误
- • 请有经验的大牛分享下Python中使用Redis作为Sessi
必知PYTHON教程 Must Know PYTHON Tutorials
- • python 解释器
- • python idle
- • python dir函数
- • python 数据类型
- • python type函数
- • python 字符串
- • python 整型数字
- • python 列表
- • python 元组
- • python 字典
- • python 集合
- • python 变量
- • python print
- • python 函数
- • python 类定义
- • python import
- • python help
- • python open
- • python 异常处理
- • python 注释
- • python continue
- • python pass
- • python return
- • python global
- • python assert
- • python if语句
- • python break
- • python for循环
- • python while循环
- • python else/elif
- • lambda匿名函数
必知PYTHON模块 Must Know PYTHON Modules
- • os 模块
- • sys 模块
- • re 正则表达式
- • time 日期时间
- • pickle 持久化
- • random 随机
- • csv 模块
- • logging 日志
- • socket网络通信
- • json模块
- • urlparse 解析URL
- • urllib 模块
- • urllib2 模块
- • robotparser 解析
- • Cookie 模块
- • smtplib 邮件
- • Base64 编码
- • xmlrpclib客户端
- • string 文本
- • Queue 线程安全
- • math数学计算
- • linecache缓存
- • threading多线程
- • sqlite3数据库
- • gzip压缩解压
最新内容 NEWS
- • django app提供pv信息的方法是什么
- • Django项目版本升级如何操作?
- • django较多数据传递如何优雅的呈现
- • django1.7获取参数问题求助
- • Django1.7使用内置comment遇到问题
- • python mysql数据库做insert操作时报_mysql_ex
- • 关于python mysql的duplicate insert机制的疑问
- • pymongo使用insert函数批量插入被中断要怎么
- • Python程序员解决棘手问题的常用库
- • 求助关于restfull api接口几个问题
图文精华 RECOMMEND
-
django1.7获取参数问题求助
-
Python程序员解决棘手问题的常用库
-
求问str()同__str__原理上有什么不同
-
scrapy框架里面用link extractor怎么能
-
python {}.fromkeys创建字典append添加操
-
python3 类型Type str doesn't support th
热点文章 HOT
- 学习Python有什么好的书籍推荐?
- Python匿名函数 Lambda表达式作用
- Python与Java、C、Ruby、PHP等编程语言有什么
- Python 正则中文网页字符串提取问题
- 如何为实时性应用存取经纬度?django my
- 想用python做个客户端,在二维码登录这个地
- 有让IDE可识别Python函数参数类型的方法吗
- Python字符串转换成列表正则疑问