Redis是什么?
1. 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在内存中设计了各种数据类型,让业务能够高速原子的访问这些数据结构,并且不 需要关心持久存储的问题,从架构上解决了前面两种存储需要走一些弯路的问题。
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原因之一。
5. 用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,详细方法见参考文献(7)。
6. 使用aof代替snapshot
Redis有两种存储方式,默认是snapshot方式,实现方法是定时将内存的快照(snapshot)持久化到硬盘,这种方法缺点是持久化之后如果出 现crash则会丢失一段数据。因此在完美主义者的推动下作者增加了aof方式。aof即append only mode,在写入内存数据的同时将操作命令保存到日志文件,在一个并发更改上万的系统中,命令日志是一个非常庞大的数据,管理维护成本非常高,恢复重建时 间会非常长,这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型,所有的优势都是建立在对内存复杂数据结构高效的原子操作 上,这样就看出aof是一个非常不协调的部分。
其实aof目的主要是数据可靠性及高可用性,在Redis中有另外一种方法来达到目的:Replication。由于Redis的高性能,复制基本没有延迟。这样达到了防止单点故障及实现了高可用。
小结
要想成功使用一种产品,我们需要深入了解它的特性。Redis性能突出,如果能够熟练的驾驭,对国内很多大型应用具有很大帮助。希望更多同行加入到Redis使用及代码研究行列。
转自:http://www.aspku.com/database/redis/44346.html
Redis是什么?的更多相关文章
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- Ignite性能测试以及对redis的对比
测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...
- mac osx 安装redis扩展
1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- Redis数据库
Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...
- redis 学习笔记(2)
redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...
- redis 学习笔记(1)
redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...
- python+uwsgi导致redis无法长链接引起性能下降问题记录
今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
- windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...
随机推荐
- fast_recovery_area无剩余空间(ORA-19815)
一.问题现象 --执行日志切换时,夯住 SQL ('/u01/oradata/oracle/redo04.log') size 50m; SQL> alter system switch log ...
- Oracle varchar2 4000
关于oracle varchar2 官方文档的描述 VARCHAR2 Data Type The VARCHAR2 data type specifies a variable-length char ...
- Python标准库之urllib,urllib2自定义Opener
urllib2.urlopen()函数不支持验证.cookie或者其它HTTP高级功能.要支持这些功能,必须使用build_opener()函数创建自定义Opener对象. 1. build_open ...
- 《深入浅出WPF》重点摘要(—)Binding自动通知机制
最近因为公司的项目需要用WPF开发,就学习了一下WPF.刚开始只是用到什么就百度什么,虽然功能是实现了,但还是没有弄清楚原理(如果不弄清原理,会感觉很心虚,整个人会没底气),所以决定找个教程系统地学一 ...
- 【译】Android系统简介—— Activity
续上一篇,继续介绍Android系统.上一篇: [译]Android系统简介 本文主要介绍构建Android应用的一些主要概念: Activity Activity是应用程序中一个单独的有UI的页面( ...
- 全部快捷方式图标变成LNK文件怎么办
windowsLNK文件打开方式恢复 相信有些用户曾试过错误地把LNK文件打开方式更改其文件导致系统所有快捷方式都失效vista与Windows7系统还普遍使用时候相信大家会有点惊慌失措要紧下面只要大 ...
- Eclipse中查看JDK类库的源代码
在Eclipse中查看JDK类库的源代码!!! 设置: 1.点 “window”-> "Preferences" -> "Java" -> & ...
- 应用层HTTP,FTP,TFTP,TELNET,DNS,EMAIL
ip路由选择 crc校验 数据包转发子模块 ttl值 ip输出队列/输入队列icmp报文 路由表 ip是网络层 tcp是传输层 应用层表示层会话层传输层网络层链路层物理层 网卡工作在链路层 网卡是工作 ...
- ASP.NET操作WMI
WMI Functions from ASP.NET Introduction This article demonstrates how to use WMI in ASP.NET to cre ...
- 从零开始学ios开发(五):IOS控件(2),Slider
下面继续学习ios的其他控件,这次会使用到的控件有Slider,当然还有一些之前已经使用过的控件Label. 这次我们不新建一个project了,当然如果你愿意重新创建一个新的项目也完全可以,我们还是 ...