REDIS4.0改进点:
- 模块系统
- 更好的复制(PSYNC2)
- 改进驱逐策略
- 线程DEL / FLUSH
- 混合RDB + AOF格式
- Raspberry Pi支持作为主要平台
- 新的MEMORY命令
- Redis Cluster支持的Nat / Docker
- 活动内存碎片整理
- 内存使用和性能改进
- 更快的Redis Cluster密钥创建
Reids概览
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库
Redis又称数据结构型服务器,支持多种数据结构(String、Hash、List、Sets等),采用客户端-服务端模式,基于TCP和简单的协议,同时也支持数据落地
1. 数据类型支持
Redis将键映射到值的类型。
值的类型确定值本身可用的操作(称为命令)。Redis支持高级,原子,服务器端操作,如交集,并集和集之间的差异以及列表,集和排序集的排序。
Redis和其他结构化存储系统之间的一个重要区别是Redis不仅支持字符串,还支持抽象数据类型:
- String: 字符串列表
- Sets: 字符串集合(非重复未排序的元素的集合)
- Sorted Sets: 排序的字符串集(由称为得分的浮点数排序的非重复元素的集合)
- Hash Table: 散列表,其中键和值是字符串
- HyperLogLogs: 用于近似集基数大小估计。
- Stream: 消费者组的条目流。
- GeoIP:自Redis 3.2以来,通过实施geohash技术的地理空间数据。
2. 数据持久化
Redis通常将全部的数据存储在内存中。2.4版本后可配置为使用虚拟内存,一部分数据集存储在硬盘上,但这个特性废弃了
默认情况下,Redis至少每2秒将数据写入文件系统,如果需要,可以使用更多或更少的健壮选项。如果在默认设置下完全系统出现故障,则只会丢失几秒钟的数据。
当前通过两种方式实现持久化:
- 使用快照,一种半持久耐用模式。不时的将
数据集
以异步方式从内存以RDB格式
写入硬盘。 - 1.1版本开始使用更安全的
AOF格式
替代,一种只能追加的日志类型
(将数据集修改操作记录起来),Redis能够在后台对只可追加的记录作修改来避免无限增长的日志。
3. 数据同步
- Redis支持主从同步,数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器,这使得Redis可执行单层树复制。
- 完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。
- 同步对读取操作的可扩展性和数据冗余很有帮助。
4. 性能问题
当不需要数据的持久性时,与考虑提交事务之前将每个更改写入磁盘的数据库系统相比,Redis的内存中性质使其能够表现良好。
Redis作为单个进程运行,并且在重写AOF(仅附加文件)时是单线程或双线程的。因此,单个的Redis实例不能利用任务的并行执行诸如存储过程。
5. 集群
Redis于2015年4月推出了3.0版本的群集(3.0版本的重大改动)
集群规范实现的Redis命令的子集:所有单键命令
是可用的,多键操作
被限制于属于同一节点。
Redis集群能够扩展到1,000个节点,实现“可接受的”写入安全性,并在某些节点发生故障时继续运行。
6. 常见用途
会话缓存,整页缓存,消息队列应用程序,排行榜和计数等
7. 版本说明
Redis借鉴了Linux操作系统对于版本号的命名规则:
版本号第二位如果是奇数,则为非稳定版本(例如2.7、2.9、3.1),如果是偶数,则为稳定版本(例如2.6、2.8、3.0、3.2),
当前奇数版本就是下一个稳定版本的开发版本,例如2.9版本是3.0版本的开发版本,所以我们在生产环境通常选取偶数版本的Redis。
各版本的大致改动内容,可以参见文末链接。
Redis 源码结构
|
|
1. server.h
专注src,redis的实现方面,4.0版本做了很大一部分重构工作,比如redis3.0中的server.c、server.h被命名成了redis.c
、redis.h
;
明白程序最好的方面是看懂它的数据结构,我们先来看server.h
。redis中所有的结构在一个叫server
的全局结构中共享配置,类型为struct redisServer
。一些重要的数据结构:
server.db
: 一组存储数据的redis数据库;server.commands
: 命令表;server.clients
: 关联一系列客户端连接到服务端的链接;server.master
: 如果实例是一个从的话,该结构代表一个特别的客户端,master客户端;
另一个重要的Redis的数据结构就是redis client
,定义了一个连接的客户端:
|
|
Redis对象的数据结构,redisObject
,这个结构可以代表了所有基础的Redis数据类型,像strings、lists、sets、sorted sets等。
|
|
2. server.c
这个是整个Redis服务的入口点,main()
函数就是在这个文件中被定义的,在启动Redis服务中,关键的几个点:
- initServerConfig() : 初始化
server
结构的默认值; - initServer(): 分配需要操作的数据结构内存,构建套接字的监听工作等等;
- aeMain(): 开启循环事件,监听新的请求,循环事件,周期性的调用的两个函数:
- serverCron(): 基于
server.hz
频率,周期性的调用执行任务,比如检测超时的客户端; - beforeSleep(): 在每次循环事件触发时候被调用,redis服务少量请求,被返回到事件循环中;
- serverCron(): 基于
其他在Redis服务中至关重要的事项:
- call(): 在给定的客户端的上下文中调用给定的命令;
- activeExpireCycle(): 处理回收基于
EXPIRE
命令设定的生存期的keys。 - freeMemoryIfNeed(): 当内存耗尽
maxmemory
设定的值时候,一个新的写命令到来时候,该函数被执行;
全局变量redisCommandTable
定义了所有的Redis命令,指定命令的名称、命令执行的函数,需要的变量参数,以及其他属性;
|
|
3. networking.c
该文件定义了所有在Redis中,clients、masters、slaves(特殊的客户端)有关的I/O函数,
- createClient(): 分配和初始化一个新的客户端
- addRply(): 基于客户端执行结果,增加结果数据到client结构中;
- writeToClient(): 传输待定数据到缓冲到客户端的输出中,当
sendReplyToClient()
执行时候也被调用; - readQueryFromClient(): 从客户端累计的数据数据中读取查询缓冲;
- processInputBuffer(): 根据Redis协议,解析客户的查询的缓冲中的数据,交给
processCommand()
执行(在server.c
中定义的)。 - freeClient():释放分配、断开连接、移除客户端;
4. aof.c和rdb.c
这两个文件是实现了Redis持久化(RDB以及AOF)。Redis使用一个持久化的模式,是基于fork
的系统调用来创建一个线程(该线程拥有Redis主线共享的内存区域)。持久化的线程,导出内存中的数据到磁盘。这个被rdb.c
使用来在磁盘上创建快照,以及aof.c
来执行AOF重写(当追加的文件过大时候);
AOF(append only file)
可以记录服务器的所有写操作。在服务器重新启动的时候,会把所有的写操作重新执行一遍,从而实现数据备份。当写操作集过大(比原有的数据集还大),Redis会重写写操作集。
5. db.c
一些特点的Redis命令操作在特定的数据类型中,比如DEL
、EXPIRE
,这些操作只能针对keys
操作,不能是其他值。所有这些命令是定义在db.c
中,相关的函数:
lookupKeyRead()
andlookupKeyWrite()
:获取一个指向关联keys的值,NULL的话代表key不存在;dbAdd()
: 其实是setKey()
的一个更高级别的副本,用于在一个redis库上面创建一个key;dbDelete()
: 移除一个key以及和他关联的值;emptyDb()
: 移除一整个db或者所有定义的db;
6. object.c
robj
结构定义了Redis的对象描述,在object.c
中,所有redis对象操作的函数在同一个级别,比如分配一个新的对象、处理引用等等:
incrRefcount()、decrRedCount()
:用于增加或者减少对象的引用,当引用到0时候,对象最终将被释放;createObject()
分配一个新的对象
7. replication.c
Redis中最复杂的文件,其中实现了主和从的角色,同时还有SYNC
、PSYNC
命令(解决主从同步或者断开连接后的一个持续复制),重要函数:
replicationFeedSlaves()
: 写命令到从客户端实例中;
相对我们的master,从客户端可以获取所有需要被执行的写;
8. 其他c文件
t_hash.c
,t_list.c
,t_set.c
,t_string.c
andt_zset.c
,包含了Redis对象类型的实现。ae.c
: Redis的循环事件相关sds.c
: redis的字符串库anet.c
: posix网络库dict.c
: 非阻塞的hash表的实现scripting.c
: lua脚本的实现;cluster.c
: redis集群的实现,(参考:http://redis.io/topics/cluster-spec)
安装
|
|
参考
- Redis主从复制:http://wiki.jikexueyuan.com/project/redis/master-slave-replication.html
- AOF持久化策略:http://wiki.jikexueyuan.com/project/redis/aof.html)
- RDB参考: http://wiki.jikexueyuan.com/project/redis/rdb.html
- Redis集群:http://redis.io/topics/cluster-spec
- Redis各版本下载:http://download.redis.io/releases/
- Redis个版本改动内容点:https://www.cnblogs.com/yangmingxianshen/p/8043851.html