Redis在计数器场景上的应用

标签: Redis | 发表时间:2013-06-05 08:00 | 作者:
出处:http://pipes.yahoo.com/pipes/pipe.info?_id=3cc4794c339ceeddc915a3c3360ef524

  对于计数器大家肯定还有或多或少的疑问。

  Q1:计数从哪里来?

  通常我们发布的社交内容会存储在数据库中,最常见的如MySQL:

  更新索引:insert into user_message(uid,messageid) values(‘xx’,’xx’)

  更新内容:insert into message_2013_05(messageid,message) values(‘xx’,'xx’);

  为什么要进行索引和内容区分我这里就不多熬述了,这时要计算我有发送了多少个message,再mysql库中select count(messageid) where uid=xxx 就可以获得我们想要得计数,也就说 大多数情况它源于我们的索引数据。

  Q2:计数和其他数据相比有什么特点?

   1.单key读写频繁,总体读取量我们认为可能比内容模块还要频繁,索引的增删改查都会导致计数器的频繁增减。尤其当某篇twitter,feed,weibo非常火爆时,单key的更新将更加火爆。

   2.需要持久化,所有用户都可能需啊知道自己的计数,这个数据和内容本身一样重要。

  从上面这两个需求来看选用Redis就是水到渠成了,而应对hotkey从Mysql update count+1 & Memcache 替换成Redis incr更是优雅很多。减少了很多数据一致性的风险。

  优化的思路:

  • 单独维护计数,从获取更新复杂度O(n)到O(1)

  我们知道随着单个uid->message的个数越来越多,而count(message_id)的逻辑复杂度是O(n),获取这个计数的成本是越来越大。如何让其获取变为O(1)?其实很简单,我们只要单独维护一下这个计数就可以了。举一个简单的例子来说明:

  假设我们有个字段,我们需要频繁的获取和更新这个字段的长度,引用 Redisbook中的一段对于redis 用于存储key value的sds的描述好像能简单的叙述这件事情。

  “

  比如说, hello world 在 C 语言中就可以表示为 "hello world\0" 。

  这种简单的字符串表示在大多数情况下都能满足要求,但是,它并不能高效地支持长度计算和追加(append)这两种操作:

  • 每次计算字符串长度(strlen(s))的复杂度为 θ(N) 。

  • 对字符串进行 N 次追加,必定需要对字符串进行 N 次内存重分配(realloc)。

  struct sdshdr {
  len = 11;
  free = 0;
  buf = “hello world\0″; // buf 的实际长度为 len + 1
  };



  通过 len 属性, sdshdr 可以实现复杂度为 θ(1) 的长度计算操作。

  ”

  • 前端还是后端维护计数,哪个更优?

   前端维护:当发生message_id的增减时,client端进行一次transaction提交,索引更新及技术更新。优点是逻辑比较简单,就是原来单次写入变成了多次写入,缺点是易引起数据不一致。

   后端维护:当数据库接收到message索引增减后,会产生相应的操作log,对于MySQL来说就是Binlog,我们根据mysql insert及delete 对索引计数进行增减操作。

  不推荐MySQL及MySQL 触发器更新的原因有如下几个:

  1.Mysql本身可能成为更新瓶颈。mysql update其实是一种重更新,在buffer pool未命中的情况下,需要把where id=xxx的page从磁盘加载到内存中,在大并发的hot key更新时,这点很有可能成为瓶颈。

  2.Mysql Replication的效率问题。Mysql Replication在如上写入更新频繁的情况下,也会成为瓶颈,当你的发了一篇feed,却发现过了一分钟计数才更新,这个肯定是不能容忍的。

  3.Mysql trigger相关bug比较多:

  如下是我们线上环境遇到的一个trigger引发的同步中断问题:http://bugs.mysql.com/bug.php?id=53079

  后端维护的思路

  

  详细可见 @jackbillow http://www.programmer.com.cn/14577/ 中使用Redis方法

  其实选择前端维护还是后端维护实际应该取决于你们公司前端及后端技术成熟程度,如果后端技术足够成熟,那么放在后端维护节省的就是大量的开发时间和降低数据一致性的风险,反之,可以放在前端进行维护。

  • Redis内存容量优化

  Redis kv数据结构如下:

  

  对于简单的k-v场景来说,最好的优化思路就是将图中Redis本身为了通用性创建的dict(16字节)及Redis Object(16字节)去除,sds的额外字节去除,这样假设你的key占用10字节,value 采用int占用4字节:

  那么去除之前可能占用的内存是:

  string类型的内存大小 = 键值个数 * (dictEntry大小16字节 + redisObject大小16字节 + 包含key的sds大小 + 包含value的sds大小) + bucket个数 * 4

  去除之后:

  string类型的内存大小 =键值个数 * (key的大小10字节 + value的4字节)+bucket个数 * 4

  当你有数亿个key的时候,节省的内容容量将会是相当可观的,当然实际优化的场景肯定会比现在列几个公式复杂,有得必有失。

  • 未来计数场景畅想

  Redis数据不能将老数据平滑过度到磁盘,无法应用到现SSD等高性能设备是硬伤。

  http://nosql.mypopescu.com/post/3745773666/redis-and-hbase-for-mozilla-grouperfish-storage 这篇文章给了不错的思考方向。

原文出处:http://www.xdata.me/?p=262

7月21日前,通过TechTarget中国专用注册码“TECH13PR”注册参加甲骨文全球大会,即可享受最低折扣!还有50元手机充值卡等您拿!活动详情请见: http://www.searchdatabase.com.cn/edm/oracle/20130515/index.html

相关 [redis 计数器 应用] 推荐:

Redis在计数器场景上的应用

- - searchdatabase
  对于计数器大家肯定还有或多或少的疑问.   通常我们发布的社交内容会存储在数据库中,最常见的如MySQL:.   更新索引:insert into user_message(uid,messageid) values(‘xx’,’xx’).   更新内容:insert into message_2013_05(messageid,message) values(‘xx’,'xx’);.

Redis应用场景

- - CSDN博客架构设计推荐文章
Redis最为常用的数据类型主要有以下:. 在具体描述这几种数据类型之前,我们先通过一张图了解下Redis内部内存管理中是如何描述这些不同数据类型的:.          首先Redis内部使用一个redisObject对象来表示所有的key和value,redisObject最主要的信息如上图所示:.

redis应用场景

- - 数据库 - ITeye博客
Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储;它的数据模型非常独特,用的是单线程. 另一个大区别在于,你可以在开发环境中使用Redis的功能,但却不需要转到Redis. 转向Redis当然也是可取的,许多开发者从一开始就把Redis作为首选数据库;但设想如果你的开发环境已经搭建好, 应用已经在上面运行了,那么更换数据库框架显然不那么容易.

[转]Redis作者谈Redis应用场景

- notsobad - heiyeluren的blog(黑夜路人的开源世界)
文章来源:http://blog.nosqlfan.com/html/2235.html. 毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象构建不同的冰箱.

Redis应用场景(转)

- - 开源软件 - ITeye博客
转自: http://blog.csdn.net/hguisu/article/details/8836819#t11.  MySql+Memcached架构的问题.   实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:.

用redis实现社交产品中计数器 - jockchou

- - 博客园_首页
社交产品业务里有很多统计计数的功能,比如:. 用户: 总点赞数,关注数,粉丝数. 帖子: 点赞数,评论数,热度. 消息: 已读,未读,红点消息数. 话题: 阅读数,帖子数,收藏数. 写的性能对MySQL是一个挑战. 可以采用redis来优化高频率写入的性能要求. 对于每一个实体的计数,设计一个hash结构的counter:.

Redis 在新浪微博中的应用

- - 大CC
Redis 在新浪微博中的应用. 支持strings, hashes, lists, sets, sorted sets. string是很好的存储方式,用来做计数存储. sets用于建立索引库非常棒;. K-V 存储 vs K-V 缓存. 新浪微博目前使用的98%都是持久化的应用,2%的是缓存,用到了600+服务器.

Mongodb与Redis应用指标对比

- - CSDN博客数据库推荐文章
    MongoDB和Redis都是NoSQL,采用结构型数据存储. 二者在使用场景中,存在一定的区别,这也主要由于. 二者在内存映射的处理过程,持久化的处理方法不同. MongoDB建议集群部署,更多的考虑到集群方案,Redis. 更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式. 丰富的数据表达、索引;最类似于关系数据库,支持丰富的查询语言.

Redis在新浪微博中的应用

- - 丕子
感觉国内对Redis玩的最转的就是新浪微博了,最近也在研究和使用Redis,准备把某些数据放到redis中. 看了几篇新浪微博的文章,挺受启发的,特别是对Redis集群扩容、内存容量配置等经验的介绍. Redis计数在新浪微博的应用. 微博关系服务与Redis的故事. Redis 在新浪微博中的应用.

Redis应用场景及产品定位

- - 互联网 - ITeye博客
关键字:Redis应用场景及产品定位. 传统MySQL+ Memcached架构遇到的问题. 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:.     MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间.