[转载]Redis几个认识误区_TIM YANG

另一些人则认为Redis是一个data structure server,由于Redis支持复杂的数据特性,好比List, Set等。对Redis的做用的不一样解读决定了你对Redis的使用方式。html

互联网数据目前基本使用两种方式来存储,关系数据库或者key value。可是这些互联网业务自己并不属于这两种数据类型,好比用户在社会化平台中的关系,它是一个list,若是要用关系数据库存储就须要转换成一种多行记录的形式,这种形式存在不少冗余数据,每一行须要存储一些重复信息。若是用key value存储则修改和删除比较麻烦,须要将所有数据读出再写入。Redis在内存中设计了各类数据类型,让业务可以高速原子的访问这些数据结构,而且不须要关心持久存储的问题,从架构上解决了前面两种存储须要走一些弯路的问题。redis

2. Redis不可能比Memcache快

不少开发者都认为Redis不可能比Memcached快,Memcached彻底基于内存,而Redis具备持久化保存特性,即便是异步的,Redis也不可能比Memcached快。可是测试结果基本是Redis占绝对优点。一直在思考这个缘由,目前想到的缘由有这几方面。数据库

  • Libevent。和Memcached不一样,Redis并无选择libevent。Libevent为了迎合通用性形成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的很多性能。Redis用libevent中两个文件修改实现了本身的epoll event loop(4)。业界很多开发者也建议Redis使用另一个libevent高性能替代libev,可是做者仍是坚持Redis应该小巧并去依赖的思路。一个印象深入的细节是编译Redis以前并不须要执行./configure。
  • CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源的方法。CAS实现须要为每一个cache key设置一个隐藏的cas token,cas至关value版本号,每次set会token须要递增,所以带来CPU和内存的双重开销,虽然这些开销很小,可是到单机10G+ cache以及QPS上万以后这些开销就会给双方相对带来一些细微性能差异(5)。

3. 单台Redis的存放数据必须比物理内存小

Redis的数据所有放在内存带来了高速的性能,可是也带来一些不合理之处。好比一个中型网站有100万注册用户,若是这些资料要用Redis来存储,内存的容量必须可以容纳这100万用户。可是业务实际状况是100万用户只有5万活跃用户,1周来访问过1次的也只有15万用户,所以所有100万用户的数据都放在内存有不合理之处,RAM须要为冷数据买单。设计模式

这跟操做系统很是类似,操做系统全部应用访问的数据都在内存,可是若是物理内存容纳不下新的数据,操做系统会智能将部分长期没有访问的数据交换到磁盘,为新的应用留出空间。现代操做系统给应用提供的并非物理内存,而是虚拟内存(Virtual Memory)的概念。数据结构

基于相同的考虑,Redis 2.0也增长了VM特性。让Redis数据容量突破了物理内存的限制。并实现了数据冷热分离。架构

4. Redis的VM实现是重复造轮子

Redis的VM依照以前的epoll实现思路依旧是本身实现。可是在前面操做系统的介绍提到OS也能够自动帮程序实现冷热数据分离,Redis只须要OS申请一块大内存,OS会自动将热数据放入物理内存,冷数据交换到硬盘,另一个知名的“理解了现代操做系统(3)”的Varnish就是这样实现,也取得了很是成功的效果。并发

做者antirez在解释为何要本身实现VM中提到几个缘由(6)。主要OS的VM换入换出是基于Page概念,好比OS VM1个Page是4K, 4K中只要还有一个元素即便只有1个字节被访问,这个页也不会被SWAP, 换入也一样道理,读到一个字节可能会换入4K无用的内存。而Redis本身实现则能够达到控制换入的粒度。另外访问操做系统SWAP内存区域时block进程,也是致使Redis要本身实现VM缘由之一。app

5. 用get/set方式使用Redis

做为一个key value存在,不少开发者天然的使用set/get方式来使用Redis,实际上这并非最优化的使用方法。尤为在未启用VM状况下,Redis所有数据须要放入内存,节约内存尤为重要。异步

假如一个key-value单元须要最小占用512字节,即便只存一个字节也占了512字节。这时候就有一个设计模式,能够把key复用,几个key-value放入一个key中,value再做为一个set存入,这样一样512字节就会存放10-100倍的容量。oop

这就是为了节约内存,建议使用hashset而不是set/get的方式来使用Redis,详细方法见参考文献(7)。

6. 使用aof代替snapshot

Redis有两种存储方式,默认是snapshot方式,实现方法是定时将内存的快照(snapshot)持久化到硬盘,这种方法缺点是持久化以后若是出现crash则会丢失一段数据。所以在完美主义者的推进下做者增长了aof方式。aof即append only mode,在写入内存数据的同时将操做命令保存到日志文件,在一个并发更改上万的系统中,命令日志是一个很是庞大的数据,管理维护成本很是高,恢复重建时间会很是长,这样致使失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型,全部的优点都是创建在对内存复杂数据结构高效的原子操做上,这样就看出aof是一个很是不协调的部分。

其实aof目的主要是数据可靠性及高可用性,在Redis中有另一种方法来达到目的:Replication。因为Redis的高性能,复制基本没有延迟。这样达到了防止单点故障及实现了高可用。

小结

要想成功使用一种产品,咱们须要深刻了解它的特性。Redis性能突出,若是可以熟练的驾驭,对国内不少大型应用具备很大帮助。但愿更多同行加入到Redis使用及代码研究行列。

参考文献

  1. On Designing and Deploying Internet-Scale Service(PDF)
  2. Facebook’s New Real-Time Messaging System: HBase To Store 135+ Billion Messages A Month
  3. What’s wrong with 1975 programming
  4. Linux epoll is now supported(Google Groups)
  5. CAS and why I don’t want to add it to Redis(Google Groups)
  6. Plans for Virtual Memory(Google Groups)
  7. Full of keys(Salvatore antirez Sanfilippo) 
相关文章
相关标签/搜索