我们可以从官网看到 Redis 的描述,如下图所示:
Redis 是一个开源的、用于在内存中存储数据的非关系型数据库。它常常被用作数据库、缓存、流式引擎以及消息中间件!其实 Redis 的初衷就是要用来作为一个消息中间件的(就是分布式系统下的生产者消费者模型),但是无心插柳柳成荫,人们发现 Redis 用来作为数据库和缓存更加的牛逼,反而在消息中间件上的作用没那么大,因为还有其它更专业的消息中间件!
可能有人会问,数据库不是有 MySQL 这些主流数据库吗,为什么还需要 Redis 呢❓❓❓
其实原因是分布式系统的诞生和需求,因为 Redis 是在内存中操作数据的,这个速度比起 MySQL 等数据库来说是要快上几个数量级的,并且在内存中存储和操作数据,更加方便在分布式主机与进程间的通信,因为 Redis 就是基于网络通信的,它可以将自己内存中的变量交给别的进程或者别的主机使用,这也是内存中普通变量做不到的;而 MySQL 这类数据库读取数据是比较慢的,并且对于分布式操作没啥方便性可言!
但是因为 Redis 是内存存储,那么缺点也很明显,就是容量太少了,和 MySQL 这类基于磁盘存储的数据库是比不了的,并且 Redis 只有在分布式系统中才能发挥威力!所以只能说各有春秋,没有最好的设计!这也就是为什么有 Redis 这么快速且便利的数据库存在,MySQL 还能立足的原因,就是因为绝大多数情况下 MySQL 提供的性能已经够用了!
那可能又会有人问,有没有容量又大,速度又快的数据库呢❓❓❓
其实最典型的方案就是将 Redis 和 MySQL 结合起来,让 Redis 作为 MySQL 的缓存,存储热点数据,因为绝大部分情况都是遵循 “二八原则” 的(也就是 20% 的热点数据,能满足 80% 的访问需求),但是带来的另一个问题就是系统的设计复杂程度就大大的提升了,并且如果数据发生修改的话,还涉及到 Redis 和 MySQL 的同步问题,所以采用何种方案要结合情况!
Redis 是一种基于键值对(key-value)的 NoSQL 数据库,与很多键值对数据库不同的是,Redis 中的值可以是由 string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,因此 Redis 可以满足很多的应用场景,而且因为 Redis 会将所有数据都存放再内存中,所以它的读写性能非常惊人。不仅如此,Redis 还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会丢失了。除了上述功能以外,Redis 还提供了键过期、发布订阅、事务、流水线、Lua 脚本等附加功能。
总之,如果在合适的场景使用好 Redis,它就会像一把瑞士军刀一样所向披靡。
2008年,Redis的作者Salvatore Sanfilippo在开发一个叫LLOOGG的网站时,需要实现一个高性能的队列功能,最开始是使用MySQL来实现的,但后来发现无论怎么优化SQL语句等都不能使网站的性能提高上去,再加上自己囊中羞涩,于是他决定自己做一个专属于LLOOGG的数据库,这个就是Redis的前身。后来,Salvatore Sanfilippo将Redis 1.0的源码发布到Github上,可能连他自己都没想到,Redis后来如此受欢迎。 假如现在有人问
Redis的作者都有谁在使用Redis,我想他可以开句玩笑的回答:还有谁不使用Redis,当然这只是开玩笑,但是从Redis的官方公司统计来看,有很多重量级的公司都在使用Redis,如国外的Stack Overflow、Github等,国内就更多了,如果单单从体量来统计,新浪微博可以说是全球最大的Redis使用者,除了新浪微博,还有像阿里巴巴、腾讯、搜狐、优酷土豆、美团、小米、唯品会等公司都是Redis的使用者。除此之外,许多开源技术像ELK等已经把Redis作为它们组件中的重要一环,而且Redis还提供了模块系统让第三方人员实现功能扩展,让Redis发挥出更大的威力。所以,可以这么说,熟练使用和运维Redis已经成为开发运维人员的一个必备技能。
Ⅱ. 常见概念
在引入架构演进之前,为避免读者对架构中的概念完全不了解导致低效沟通,优先对其中一些比较重要的概念做前置介绍:
- 应用(
Application) / 系统(System):一个应用是一组服务器程序构成的。 - 模块(
Module) / 组件(Component):一个应用中有多个独立的功能,这些功能就可以称为模块或者组件。 - 分布式(
Distributed):就是引入多台主机或者服务器,协同配合完成一系列的动作,强调的是物理上的多台主机。 - 集群(
Cluster):和分布式很像,也是引入多台主机或者服务器,协同配合完成一系列的动作,不同的是强调的是逻辑上的多台主机。 - 主(
Master) / 从(Slave):集群中,通常有一个程序需要承担更多的职责,被称为主,其他承担附属职责的被称为从。 - 中间件(
Middleware):与业务无关的服务,即功能更通用的服务,比如数据库、缓存、消息队列等。
Ⅲ. 浅谈分布式系统
一、单机架构
初期,我们需要利用我们精干的技术团队,快速将业务系统投入市场进行检验,并且可以迅速响应变化要求。但好在前期用户访问量很少,没有对我们的性能、安全等提出很高的要求,而且系统架构简单,无需专业的运维团队,所以选择单机架构是合适的。
简单地说,单机架构就是只有一台服务器,这台服务器负责所有的工作!如下图所示:
用户在浏览器中输入 www.baidu.com,首先经过 DNS 服务将域名解析成 IP 地址 10.102.41.1,随后浏览器访问该 IP 对应的应用服务。其中应用服务就是用 C++/Java 编写的服务器程序,而数据库服务就是 MySQL 的服务端,当应用服务收到了请求之后转化为对应的 SQL 语句比如 select,则会向数据库服务进行 select 操作,得到结果后进行返回!
虽说是单机架构,但是别小瞧它,因为现在大部分的硬件设备都是很不错的,就算是单机架构也能满足大部分的需求,并且依然是现在市场的主流!
Web服务软件一般有:Tomcat、Netty、Nginx、Apache等。数据库软件一般有:
MySQL、Oracle、PostgreSQL、SQL Server等。
二、什么是分布式系统
从上面的单机架构就能看出,一台主机的硬件一定也是有上限的,这取决于它的资源情况比如 CPU、内存、硬盘、网络等等,而服务器每次收到一个请求,就会消耗对应的资源,如果同一时刻需要处理的请求太多了,此时就很有可能出现某个资源不够用了,很可能就导致服务器的处理请求时间变长甚至处理出错,此时就会有两个思路来缓解这个问题:
- 开源
- 节流
节流,就是在软件上进行优化,通过一些性能测试,找出程序的一些瓶颈点进行对症下药,但是这对程序员的水平要求就比较高了!
开源,就是添加更多的硬件资源!因为一台主机上的资源始终是有限的,这很大程度取决于它的主板拓展能力,但是这对于一些场景还是不够用,所以就需要引入多台主机了,而一旦引入了多台主机,这个系统就可以称为分布式系统了!
但不是说随随便便接上多台主机就能执行处理的,还需要在软件上进行一系列的调整以及适配,这也很考验程序员的水平!并且分布式系统的引入其实是迫不得已的,因为系统的复杂程度会大大提升,这对于程序员来说带来的问题就是出现 bug 的概率大大提升,也就是加班的次数变多,甚至可能导致年终奖丢失的概率提升等等问题……
所以分布式系统,其实是无奈之举,这个要理解清楚!
三、应用数据分离架构
简单的了解分布式系统之后,我们就可以引入应用数据分离架构了,其实就是一台主机负责应用服务,另一台主机负责数据库服务,此时我们可以根据需求不同,为两台主机提供不同的配置!
比如负责应用服务的主机可能会处理很多业务,那就比较吃 CPU 和内存,所以可以给它配置好一点的 CPU 和内存;而负责数据库服务的主机则需要大容量的硬盘空间,并且需要有快一点的数据访问速度,就可以考虑配置更大硬盘容量,甚至可以上 SSD 也就是固态硬盘提高速度!
四、应用服务集群架构
所谓应用服务集群架构,就是增加应用服务器的个数,相当于就增加了处理业务所需要的硬件资源,这在大部分情况下都是比单独为一台应用服务器升级性能要来得更有性价比!
如下图所示,应用服务器就有多台,然后它们处理完业务之后就交给存储服务器进行处理,注意这里应用服务器不止是图中画的,图中的 scale out 就表示横向拓展的意思,表示有多台应用服务器!

此时就引入了一个问题,就是上图中的负载均衡机制,它的引入是为了防止某些主机被频繁的使用而一些主机又被闲置着,这相当于是浪费了资源,所以负载均衡就能很好的解决这个问题!
进行负载均衡的其实也是一台主机,一般称为网关服务器,它是一个单独的服务器!假设有 1w 个用户请求,有两台应用服务器,此时按照一般的负载均衡规则,就是每台应用服务器处理 5k 个请求!
并且我们需要知道的是,负载均衡既然是一个服务器,所有的请求都会先经过它,所以它的处理能力肯定是要比其它应用服务器强的!
常见的负载均衡软件有:Nginx、HAProxy、LVS、F5 等。
其中负载均衡算法(也成为流量调度算法)也有很多种,这里简单介绍几种较为常见的:
Round-Robin轮询算法。即非常公平地将请求依次分给不同的应用服务器。Weight-Round-Robin轮询算法。为不同的服务器(比如性能不同)赋予不同的权重(weight),能者多劳。- 一致哈希散列算法。通过计算用户的特征值(比如
IP地址)得到哈希值,根据哈希结果做分发,优点是确保来自相同用户的请求总是被分给指定的服务器,也就是我们平时遇到的专项客户经理服务。
五、读写分离/主从分离架构
虽然上面我们将应用服务器分离减少了单台应用服务器的压力,但是存储服务器也就是数据库的负载还是那么大,所以我们对数据库也要引入多台服务器进行管理!
我们采用的解决办法是这样的,保留一个主要的数据库作为写数据库,其他的数据库作为从属数据库负责读。从库的所有数据全部来自主库的数据,经过同步后,从库可以维护着与主库一致的数据。然后为了分担数据库的压力,我们可以将写数据请求全部交给主库处理,但读请求分散到各个从库中。由于大部分的系统中,读写请求都是不成比例的,例如 100 次读 1 次写,所以只要读请求由各个从库分担之后,数据库的压力就没有那么大了。
当然这个过程不是无代价的,主库到从库的数据同步其实是有时间成本的,但这个问题我们暂时不做进一步探讨!

应用中需要对读写请求做分离处理,所以可以利用一些数据库中间件,将请求分离的职责托管出去。
常见的数据库中间件有:MyCat、TDDL、Amoeba、Cobar 等。
六、冷热数据分离架构 -- 引入缓存
随着访问量继续增加,会发现数据库有个天然的问题,就是响应速度慢!并且我们发现业务中一些数据的读取频率远大于其他数据的读取频率。我们把这部分数据称为热点数据,与之相对应的是冷数据。针对热数据,为了提升其读取的响应时间,可以增加本地缓存,并在外部增加分布式缓存,缓存热门商品信息或热门门商品的 html 页面等。通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。
其中涉及的技术包括:使用 memcached 作为本地缓存,使用 Redis 作为分布式缓存。所以虽然引入缓存能提高整体服务器的性能,但是也引入了很多复杂的问题,比如缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题。

常见的缓存软件有:Memcached、Redis 等。
七、数据库分库分表
上面我们引入了主从数据库来减少数据库的负载,但是还有问题,就是随着业务的数据量增大,大量的数据存储在同一个库中已经显得有些力不从心了,所以可以按照业务场景,将数据分开存储!比如针对评论数据,可按照商品 ID 进行 hash 路由到对应的表中存储;针对支付记录,可按照小时创建表,每个小时表继续拆分为小表,使用用户 ID 或记录编号来路由数据。
只要实时操作的表数据量足够小,请求能够足够均匀的分发到多台服务器上的小表,那数据库就能通过水平扩展的方式来提高性能。其中前面提到的 Mycat 也支持在大表拆分为小表情况下的访问控制。这种做法显著的增加了数据库运维的难度,对 DBA 的要求较高。
数据库设计到这种结构时,已经可以称为分布式数据库,但是这只是一个逻辑的数据库整体,数据库里不同的组成部分是由不同的组件单独来实现的,如分库分表的管理和请求分发,由 Mycat 实现,SQL 的解析由单机的数据库实现,读写分离可能由网关和消息队列来实现,查询结果的汇总可能由数据库接口层来实现等等,这种架构其实是 MPP(大规模并行处理)架构的一类实现!

相关软件有:Greenplum、TiDB、Postgresql XC、HAWQ等;商用的如南大通用的GBase、睿帆科技的雪球**DB、华为的LibrA** 等。
八、微服务架构 -- 业务拆分
随着人员增加以及业务发展,我们将业务分给不同的开发团队去维护,每个团队独立实现各自的微服务,然后互相之间对数据的直接访问进行隔离,可以利用 Gateway、消息总线等技术,实现相互之间的调用关联,甚至可以把一些类似用户管理、安全管理、数据采集等业务提成公共服务。
引入微服务架构,有利于代码的维护,将一个复杂的服务器拆分为多个功能单一的服务器管理!也有利于代码的复用,业务一个微服务是可以在不同的地方使用的,需要的话就单独拿出来使用;此外不同的服务划分管理可以进行不同的部署,对于需求量不大的服务则可以减少资源的提供!
更本质的说,微服务其实解决的就是人的问题,因为微服务就相当于一个程序的子函数,将一个复杂的程序分解为子函数之后是便于管理的!

但是微服务也带来了很多问题,比如系统性能下降,因为多个微服务之间是通过网络通信的,要知道网络通信比读取硬盘还慢,所以这对网卡、交换机、路由器等通信设备的要求就变高了,也就是需要花费更多的资源去解决性能下降问题,这对大部分的企业来说是很大的负担,所以一般只有大厂才会有微服务架构!
此外微服务还会导致系统的复杂性提高,就需要有一系列的措施来保证系统的可用性,比如上图提到的安全中心等措施!
小结
至此,一个还算合理的高可用、高并发系统的基本雏形已显。注意,以上所说的架构演变顺序只是针对某个侧面进行单独的改进,在实际场景中,可能同一时间会有几个问题需要解决,或者可能先达到瓶颈的是另外的方面,这时候就应该按照实际问题实际解决。如在政府类的并发量可能不大,但业务可能很丰富的场景,高并发就不是重点解决的问题,此时优先需要的可能会是丰富需求的解决方案。
对于单次实施并且性能指标明确的系统,架构设计到能够支持系统的性能指标要求就足够了,但要留有扩展架构的接口以便不备之需。对于不断发展的系统,如电商平台,应设计到能满足下一阶段用户量和性能指标要求的程度,并根据业务的增长不断的迭代升级架构,以支持更高的并发和更丰富的业务。
而所谓的 “大数据” 其实是海量数据采集清洗转换、数据存储、数据分析、数据服务等场景解决方案的一个统称,在每一个场景都包含了多种可选的技术,如数据采集有 Flume、Sqoop、 Kettle 等, 数据存储有分布式文件系统 HDFS、FastDFS, NoSQL 数据库 HBase、MongoDB 等,数据分析有 Spark 技术栈、机器学习算法等。总的来说大数据架构就是根据业务的需求,整合各种大数据组件组合而成的架构,一般会提供分布式存储、分布式计算、多维分析、数据仓库、机器学习算法等能力。而服务端架构更多指的是应用组织层面的架构,底层能力往往是由大数据架构来提供。
Ⅳ. Redis 的特性
一、速度快
正常情况下,Redis 执行命令的速度非常快,官方给出的数字是读写性能可以达到 10w/秒,当然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了 Redis 如此之快,可以大概归纳为以下几点:
Redis的所有数据都是存放在内存中的,下图是谷歌公司2009年给出的各层级硬件执行速度,所以把数据放在内存中是Redis速度快的最主要原因。Redis是用C语言实现的,相比于其它语言来说,C语言实现的程序 “距离” 操作系统更近,执行速度相对会更快。Redis使用单线程,预防了多线程可能产生的竞争问题。(Redis在6.0版本引入了多线程机制,但主要也是在处理网络和IO,不涉及到数据命令,即命令的执行仍然采用了单线程模式。)- 从网络通信角度来说,
Redis采用了IO多路复用的方式(也就是epoll模型),提高了单线程的处理效率。 - 作者对于
Redis源代码可以说是精打细磨,曾经有人评价Redis是少有的集性能和优雅于一身的开源代码。

二、基于键值对的数据结构服务器
几乎所有的编程语言都提供了类似字典的功能,例如 C++ 里的 map、Java 里的 map、Python 里的 dict 等,类似于这种组织数据的方式叫做基于键值对的方式,与很多键值对数据库不同的是,Redis 中的值不仅可以是字符串,而且还可以是具体的数据结构,这样不仅能便于在许多应用场景的开发,同时也能提高开发效率。
Redis 的全称是 REmote Dictionary Server,它主要提供了 5 种数据结构:字符串(string) 、哈希(hash) 、列表(list) 、集合(set) 、有序集合(ordered set/zet),同时在字符串的基础之上演变出了位图(Bitmaps) 和 HyperLogLog 两种神奇的数据结构,并且随着 LBS (Location Based Service基于位置服务)的不断发展,Redis 3.2 版本中加入有关 GEO(地理信息定位)的功能,总之在这些数据结构的帮助下,开发者可以开发出各种有意思的应用。
三、丰富的功能
- 提供了键过期功能,可以用来实现缓存。
- 提供了发布订阅功能,可以用来实现消息系统。
- 支持
Lua脚本功能,可以利用Lua创造出新的Redis命令。 - 提供了简单的事务功能,能在一定程度上保证事务特性。
- 提供了流水线(
Pipeline)功能,这样客户端能将一批命令一次性传到Redis,减少了网络的开销。
四、简单稳定
Redis 的简单特性主要表现在三个方面:
- 首先,
Redis的源码很少,早期版本的代码只有两万行左右,**3.0**版本以后由于添加了集群特性,代码增至五万行左右,相对于很多NoSQL数据库来说代码量相对要少很多,也就意味着普通的开发和运维人员完全可以吃透它。 - 其次,
Redis使用单线程模型,这样不仅使得Redis服务端处理模型变得简单,而且也使得客户端开发变得简单。 - 最后,
Redis不需要依赖于操作系统中的类库(例如Memcache需要依赖libevent这样的系统类库),因为Redis自己实现了事件处理的相关功能。
但与简单相对的是 Redis 具备相当的稳定性,在大量使用过程中,很少出现因为 Redis 自身 BUG 而导致宕掉的情况。
五、客户端支持的语言多
Redis 提供了简单的 TCP 通信协议,很多编程语言可以很方便地接入到 Redis,并且由于 Redis 受到社区和各大公司的广泛认可,所以支持 Redis 的客户端语言也非常多,几乎涵盖了主流的编程语言,例如 C/C++、Java、 PHP、 Python、 NodeJS 等,后续我们会对 Redis 的客户端使用做详细说明。
六、持久化(Persistence)
通常看,将数据放在内存中是不安全的,因为内存具有易失性,一旦发生断电或者机器故障,重要的数据可能就会丢失,因此 Redis 提供了两种持久化方式:RDB 和 AOF。即可以用两种策略将内存的数据保存到硬盘中,如下图所示,这样就保证了数据的可持久性,后续我们将对 Redis 的持久化进行详细说明。
七、主从复制(Replication)
Redis 提供了复制功能,实现了多个相同数据的 Redis 副本,如下图所示。复制功能是分布式 Redis 的基础,后续我们会对 Redis 的复制功能进行详细演示。
八、高可用(High Availability)和分布式(Distributed)
Redis 提供了高可用实现的 Redis 哨兵(Redis Sentinel), 能够保证 Redis 结点的故障发现和故障自动转移。
此外还提供了 Redis 集群(Redis Cluster),是真正的分布式实现,提供了高可用、读写和容量的扩展性。
Ⅴ. Redis 使用场景
一、适用场景
① 缓存
缓存机制几乎在所有大型网站都有使用,合理地使用缓存不仅可以加速数据的访问速度,而且能够有效地降低后端数据源的压力。Redis 提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一个网站的稳定保驾护航。
② 排行榜系统
排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis 提供了列表和有序集合的结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。
③ 计数器应用
计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加一的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis 天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。
④ 社交网络
赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太合适保存这种类型的数据,Redis 提供的数据结构可以相对比较容易地实现这些功能。
⑤ 消息队列系统
注意这里说的消息队列和我们学 linux 时候谈到的消息队列是两码事!其实消息队列就是网络版本的生产者消费者模型,而我们之前学的一直都是在一台主机上的生产者消费者模型。
消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis 提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,比如 RabbitMQ、Kafka、RocketMQ 等消息队列,但是对于一般的消息队列功能基本可以满足。
二、不适用的场景
实际上和任何一门技术一样,每个技术都有自己的应用场景和边界,也就是说 Redis 并不是万金油,有很多合适它解决的问题,但是也有很多不合适它解决的问题。我们可以站在数据规模和数据冷热的角度来进行分析。
站在数据规模的角度看,数据可以分为大规模数据和小规模数据,我们知道 Redis 的数据是存放在内存中的,虽然现在内存已经足够便宜,但是如果数据量非常大,例如每天有几亿的用户行为数据,使用 Redis 来存储的话,基本上是个无底洞,经济成本相当高。
站在数据冷热的角度,数据分为热数据和冷数据,热数据通常是指需要频繁操作的数据,反之为冷数据,例如对于视频网站来说,视频基本信息基本上在各个业务线都是经常要操作的数据,而用户的观看记录不一定是经常需要访问的数据,这里暂且不讨论两者数据规模的差异,单纯站在数据冷热的角度上看,视频信息属于热数据,用户观看记录属于冷数据。如果将这些冷数据放在 Redis 上,基本上是对于内存的一种浪费,但是对于一些热数据可以放在 Redis 中加速读写,也可以减轻后端存储的负载,可以说是事半功倍。
所以,Redis 并不是万金油,相信随着我们对 Redis 的逐步学习,能够清楚 Redis 真正的使用场景!
Ⅵ. Redis 重大版本
Redis 借鉴了 Linux 操作系统对于版本号的命名规则:版本号第二位如果是奇数,则为非稳定版本(例如**2.7、2.9、3.1**) ,如果是偶数,则为稳定版本。当前奇数版本就是下一个稳定版本的开发版本,例如 2.9 版本是 3.0 版本的开发版本。
所以我们生产环境通常选取偶数版本的 Redis,如果对于某些新的特性想提前了解和使用,可以选择最新的奇数版本。目前最新的版本是 7.0 版本。
一、Redis 2.6
在 2012 年正式发布,相比于 Redis 2.4,主要特性如下:
- 服务端支持
Lua脚本 - 去掉虚拟内存相关功能。
- 放开对客户端连接数的硬编码限制。
- 键的过期时间支持毫秒。
- 从结点提供只读功能。
- 两个新的位图命令:
bitcount和bitop。 - 增强了
redis-benchmark的功能:支持定制化的压测、CSV格式输出等功能。 - 基于浮点数自增命令:
incrbyfloat和hincrbyfloat。 redis-cli可以使用--eval参数实现Lua脚本执行。shutdown命令增强。Info可以按照setction输出,并且添加了一些统计项。- 重构了大量的核心代码,所有集群相关的代码都去掉了,会在
3.0支持cluster功能。 sort命令优化。
二、Redis 2.8
在 2013 年正式发布,相比于 Redis 2.6,主要特性如下:
- 添加部分主从复制的功能,在一定程度上降低了由于网络问题,造成频繁全量复制生成
RDB对系统造成的压力。 - 尝试性地支持
IPv6。 - 可以通过
config set命令设置maxclients。 - 可以用
bind命令绑定多个IP地址。 Redis设置了明显的进程名,方便使用ps命令查看系统进程。config rewrite命令可以将config set持久化到Redis配置文件中。- 发布订阅添加了
pubsub命令。 Redis Sentinel第二版,相比于Redis 2.6的Redis Sentinel,此版本已经变成生产可用。
三、Redis 3.0
在 2015 年正式发布,相比于 Redis 2.8,主要特性如下:
Redis Cluster:Redis提供的官方分布式实现。- 全新的
embedded string对象编码结果,优化了小对象内存访问,在特定的工作负载时,下载速度大幅提高。 - 优化了
LRU算法,大幅提供性能。 migrate链接缓存,大幅提供键迁移的速度。migrate命令新增两个参数:copy和replace。client pause命令,在指定时间内中止处理客户端请求。bitcount命令性能提高。config set设置maxmemory时候能够设置不一样的单位(以前只能是字节)。Redis日志中会反应当前实例的角色(master或者slave)。incr命令性能提高。
四、Redis 3.2
在 2016 年正式发布,相比于 Redis 3.0,主要特性如下:
- 添加
GEO相关功能。 SDS在速度和节省空间上都作了优化。- 支持使用
upstart或者systemd管理Redis进程。 - 新的
List编码类型:quicklist。 - 从节点读取过时数据保证一致性。
- 添加了
hstrlen命令。 - 加强了
debug命令,支持了更多的参数。 Lua脚本功能加强。- 添加了
Lua Debugger。 config set支持更多的配置参数。- 优化了
Redis崩溃后的相关报告。 - 新的
RDB格式,可是仍然兼容旧的RDB。 - 加速
RDB的加载速度。 spop命令支持个数参数。cluster nodes命令获得加速。Jemalloc更新到4.0.3版本。
五、Redis 4.0
在 2017 年正式发布,相比于 Redis 3.2,主要特性如下:
- 提供了模块系统(
module),方便第三方开发者拓展Redis的功能。 PSYNC 2.0:优化了以前版本中,主从节点切换必然引发全量复制的问题。- 提供了新的缓存剔除算法:
LFU(Last Frequently Used),注意LFU和LRU算法的不同之处,LRU的淘汰规则是基于访问时间,而LFU是基于访问次数的,并对已有算法进行了优化。 - 提供了非阻塞
del和flushall/flushdb功能,新添加了unlink命令, 这个命令是del命令的异步版本, 它可以将删除指定键的操作放在后台线程里面执行。 - 提供了
memory命令,实现对内存更为全面的监控统计。 - 提供了交互数据库功能,实现
Redis内部数据库的数据置换。 - 提供了
RDB-AOF混合持久化格式,充分利用了AOF和RDB各自优点。 Redis Cluster兼容NAT和docker。
六、Redis 5.0
在 2018 年正式发布,相比于 Redis 4.0,主要特性如下:
- 新的流数据类型(
stream)。 - 新的
Redis模块API:定时器、集群和字典API。 RDB现在可存储LFU和LRU信息。redis-cli中的集群管理器从Ruby(redis-trib.rb)移植到了C语言代码。执行redis-cli --cluster help命令以了解更多信息。- 新的有序集合(
sorted set)命令:zpopmin/zpopmax和阻塞变体(blocking variants)。 - 升级
Active defragmentation至v2版本。增强HyperLogLog的实现。 - 更好的内存统计报告。
- 许多包含子命令的命令现在都有一个
help子命令。 - 客户端频繁连接和断开连接时,性能表现更好。
- 许多错误修复和其他方面的改进。
- 升级
Jemalloc至5.1版本。 - 引入
client unblock和client id。 - 新增
lolwut命令。 - 在不存在需要保持向后兼容性的地方,弃用户
"slave"术语。 - 网络层中的差异优化。
- 增强对
Lua的支持:将Lua脚本更好地传播到replicas/AOF、Lua脚本现在可以超时并在副本中进入-BUSY状态。 - 引入动态的
HZ(Dynamic HZ)以平衡空闲CPU使用率和响应性。 - 对
Redis核心代码进行了重构并在许多方面进行了改进。
七、Redis 6.0
在 2020 年正式发布,相比于 Redis 5.0,主要特性如下:
Redis 6.0引入多线程IO,但多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。- 实现了**
client-side-caching(客户端缓存)功能。放弃了caching slot**,而只使用key names。 Redis 6.0开始在兼容RESP 2的基础上,开始支持RESP 3(Redis SerializationProtocol是Redis服务端与客户端之间通信的协议)。- 连接支持
SSL,更加安全。 - 增强
ACL权限控制:支持对客户端的权限控制,实现对不同的key授予不同的操作权限、新增一个新的ACL日志命令,允许查看所有违反ACL的客户机、访问不应该访问的命令、访问不应该访问的密钥,或者验证尝试失败。这对于调试ACL问题非常有用。 - 提升了
RDB日志加载速度。 - 发布官方的
Redis集群代理模块Redis Cluster Proxy。 - 提供了众多的新模块(
modules)API。
八、Redis 7.0
在 2022 年正式发布,相比于 Redis 6.0,主要特性如下:
- 将
AOF文件的存储方式改为在一个文件夹下存储多个文件。 - 将持久化文件
RDB的版本升级为10,与之前的RDB文件版本不再兼容。 - 在读取老的
RDB文件格式的时候将ziplist转换为listpack,这种转换发生于两种情况之下:从磁盘读取文件或者从一个主节点进行复制文件的时候。 - 在
redis.conf配置文件中,protected-mode默认更改为yes,只有当你希望你的客户端在没有授权的情况下可以连接到Redis server的时候可以将protected-mode设置为no。 - 在
ACL中,pub/sub channel默认是被阻塞的。 - 在从节点中,
TTL的时间标识的是绝对时间,不再是相对时间,从而保证了过期数据被及时删除。 - 不再支持
gopher协议。 - 当在配置文件中设置
replica-serve-stale-data=no, 当主节点不再提供服务时,ping命令得不到返回值。