对Redis的理解,Redis是什么,Redis和Memcache谁快?

soゝso 2017-08-31 22:26:57 19094

    前段时间微博发生了一起大的系统故障,结果说是因为Redis集群的问题,很多技术的朋友都比较关心,其中的原因不会超出James Hamilton On Designing and Deploying Internet-Scale Service 概括的那几个范围,James 第一条经验“Design for failure ”是所有互联网架构成功的一个关键。互联网系统的工程理论其实非常简单,James paper 中内容几乎称不上理论,而是多条实践经验分享,每个公司对这些经验的理解及执行力决定了架构成败。

    题外话说完,最近又研究了  Redis  。去年曾做过一个MemcacheDB, Tokyo Tyrant, Redis performance test ,到目前为止,这个benchmark 结果依然有效。这1年我们经历了很多眼花缭乱的key / value 存储产品的诱惑,从Cassandra的淡出(Twitter 暂停在主业务使用)到Hbase 的兴起(Facebook新的邮箱业务选用HBase),当再回头再去看Redis,发现这个只有1万多行源代码的程序充满了神奇及大量未经挖掘的特性。Redis性能惊人,国内前十大网站的子产品估计用1台Redis就可以满足存储及Cache的需求。除了性能印象之外,业界其实普遍对Redis的认识存在一定误区。本文提出一些观点供大家探讨。

一、 Redis是什么?

    这个问题的结果影响了我们怎么用  Redis  。如果你认为  Redis  是一个key value store , 那可能会用它来代替  MySQL  ;如果认为它是一个可以持久化的cache , 可能只是它保存一些频繁访问的临时数据。  Redis  是REmote DIctionary Server 的缩写,在  Redis  在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems ,这个定义偏向key value store 。还有一些看法则认为  Redis  是一个memory database ,因为它的高性能都是基于内存操作的基础。另外一些人则认为  Redis  是一个data structure server ,因为Redis支持复杂的数据特性,比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。

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

二、Redis不可能比Memcache快?

    很多开发者都认为  Redis  不可能比  Memcached  快,  Memcached  完全基于内存,而Redis 具有持久化保存特性,即使是异步的,Redis 也不可能比Memcached 快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因,目前想到的原因有这几方面。

    Libevent Memcached 不同,Redis并没有选择Libevent Libevent 为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent 中两个文件修改实现了自己的epoll event loop 。业界不少开发者也建议Redis使用另外一个libevent高性能替代libev,但是作者还是坚持Redis应该小巧并去依赖的思路。一个印象深刻的细节是编译Redis之前并不需要执行./configure

    CAS 问题。CAS Memcached 中比较方便的一种防止竞争修改资源的方法。CAS 实现需要为每个cache key设置一个隐藏的cas token cas 相当value 版本号,每次set token 需要递增,因此带来CPU和内存的双重开销,虽然这些开销很小,但是到单机10G+ cache以及QPS 上万之后这些开销就会给双方相对带来一些细微性能差别。

三、单台Redis的存放数据必须比物理内存小

  Redis  的数据全部放在内存带来了高速的性能,但是也带来一些不合理之处。比如一个中型网站有100万注册用户,如果这些资料要用Redis来存储,内存的容量必须能够容纳这100万用户。但是业务实际情况是100万用户只有5万活跃用户,1周来访问过1次的也只有15万用户,因此全部100万用户的数据都放在内存有不合理之处,RAM需要为冷数据买单。

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

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

四、Redis的VM实现是重复造轮子

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

作者antirez在解释为什么要自己实现VM中提到几个原因。主要OS的VM换入换出是基于Page 概念,比如OS VM1 Page 是4K, 4K中只要还有一个元素即使只有1个字节被访问,这个页也不会被SWAP, 换入也同样道理,读到一个字节可能会换入4K无用的内存。而Redis自己实现则可以达到控制换入的粒度。另外访问操作系统SWAP内存区域时block进程,也是导致Redis要自己实现VM原因之一。

五、用get / set方式使用Redis

作为一个key / value 存在,很多开发者自然的使用set/get 方式来使用  Redis  ,实际上这并不是最优化的使用方法。尤其在未启用VM 情况下,Redis 全部数据需要放入内存,节约内存尤其重要。

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

这就是为了节约内存,建议使用hashset而不是set/get的方式来使用Redis。

六、使用aof代替snapshot

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

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

版权所属:SO JSON在线解析

原文地址:https://www.sojson.com/blog/243.html

转载时必须以链接形式注明原始出处及本声明。

本文主题:

如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。

相关文章
JSON是什么?它能带来什么?它和XML比较?
Redis缓存淘汰算法,LRU算法,LRU算法讲解。
Description的作用,Description对SEO有什么影响
为什么undefined、NaN和Infinity可以被赋值,而null不可以?
为什么很多第三方接口,都改成了基于http,直接传递json数据的方式来代替webservice?
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比
什么是Referer?Referer的作用?空Referer是怎么回事?
Java Redis线程池ShardedJedisPool 使用方法,Java Jedis连接池的使用
Redis 单线程模型分析
Redis与Memcached的比较 ,然后选择了Redis
最新文章
ICP怎么操作取消备案,企业、个人怎么自己申请取消备案? 15
Javascript 加密/压缩后运行不了,JavaScript报错排查讲解 41
JavaScript 不可逆加密问题排查之方案一(闭包优化) 45
Java爬虫,Jsoup 爬取大众点评、美团商家信息电话号码解决方案 241
分解质因数 JavaScript 计算方式,及分解质因数讲解 7
湖南腾众4s店服务怎么样?进来看看你就知道了 29
SEO 之 SpringMVC redirect 301,301和302区别详细讲解 82
网站如何设置404页面、500等错误页面,有什么漏洞?怎么预防? 101
Java 文字转图片输出,Java 输出透明背景图片,Java文字转图片防爬虫 153
HttpClient获取访问域名的真实ip,HttpClient请求获取目标IP地址 298
最热文章
免费天气API,全国天气 JSON API接口,可以获取五天的天气预报 175159
Elasticsearch教程(四) elasticsearch head 插件安装和使用 138291
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比 117906
Elasticsearch教程(六) elasticsearch Client创建 81985
Elasticsearch教程(一),全程直播(小白级别) 77083
Elasticsearch教程(二),IK分词器安装 77056
Elasticsearch教程(八) elasticsearch delete 删除数据(Java) 76748
苹果电脑Mac怎么恢复出厂系统?苹果系统怎么重装系统? 75096
Elasticsearch教程(五) elasticsearch Mapping的创建 69391
Elasticsearch教程(三),IK分词器安装 (极速版) 58147

骚码加入我们 / 千人QQ群:259217951

入群需要5元,如果没有QQ钱包,可以先Alipay、微信,赞助然后加群主拉进。

二维码生成 来自 >> 二维码生成器

支付扫码

所有赞助/开支都讲公开明细,用于网站维护:赞助名单查看

正在加载... ...