目录
Redis 文献资料
注意:Redis文档还可以在redis-doc github存储库中以原始(计算机友好)格式获得。Redis文档是根据Creative Commons Attribution-ShareAlike 4.0 International许可发布的。
用Redis编程
- Redis实现的命令的完整列表,以及每个命令的详尽文档。
- 流水线:了解如何一次发送多个命令,以节省往返时间。
- Redis发布/订阅:Redis是一个快速,稳定的发布/订阅消息传递系统!一探究竟。
- Redis Lua脚本编制:Redis Lua脚本编制功能文档。
- 调试Lua脚本:Redis 3.2引入了用于Redis脚本的本地Lua调试器。
- 内存优化:了解Redis如何使用RAM并学习一些技巧以减少使用RAM。
- 过期:Redis允许为每个密钥设置不同的生存时间,以便密钥过期后会自动将其从服务器中删除。
- Redis作为LRU缓存:如何配置和使用Redis作为具有固定内存量和自动退出键的缓存。
- Redis事务:可以将命令分组在一起,以便将它们作为单个事务执行。
- 客户端缓存:从版本6开始,Redis支持服务器辅助的客户端缓存。本文档介绍了如何使用它。
- 大量插入数据:如何在短时间内向Redis实例添加大量现有或生成的数据。
- 分区:如何在多个Redis实例之间分配数据。
- 分布式锁:使用Redis实现分布式锁管理器。
- Redis键空间通知:通过Pub / Sub(Redis 2.8或更高版本)获取键空间事件的通知。
- 使用Redis 创建二级索引:使用Redis数据结构创建二级索引,组合索引和遍历图。
Redis模块API
- Redis模块简介。一个开始学习Redis 4.0模块编程的好地方。
- 实现本机数据类型。扫描的模块实现了看起来像内置数据类型的新数据类型(数据结构等)。本文档介绍了这样做的API。
- 使用模块阻止操作。这仍然是一种实验性的API,但是它是一种非常强大的API,用于编写可以阻止客户端(而不阻止Redis)并可以在其他线程中执行任务的命令。
- Redis模块API参考。从顶部注释直接在源代码里面生成
src/module.c
。包含有关API使用情况的许多低级详细信息。
教程和常见问题解答
- Redis数据类型简介:这是学习Redis API和数据模型的良好起点。
- Redis流介绍:Redis 5新数据类型Stream的详细描述。
- 用PHP和Redis编写一个简单的Twitter克隆
- 使用Redis自动完成
- 数据类型简短摘要:Redis支持的不同类型的值的简短摘要,不像本节中列出的第一个教程那样更新且信息丰富。
- 常见问题解答:有关Redis的一些常见问题。
管理
- Redis-cli:了解如何掌握Redis命令行界面,这是您经常使用的一些东西,用于管理,诊断Redis并对其进行故障排除和试验。
- 配置:如何配置Redis。
- 复制:设置主副本复制所需的知识。
- 持久性:配置Redis的持久性时了解您的选择。
- Redis管理:选定的管理主题。
- 安全性:Redis安全性概述。
- Redis访问控制列表:从版本6开始,Redis支持ACL。可以将用户配置为只能运行选定的命令,并且只能访问特定的键模式。
- 加密:如何加密Redis客户端-服务器通信。
- 信号处理:Redis如何处理信号。
- 连接处理:Redis如何处理客户端连接。
- 高可用性:Redis Sentinel是Redis的官方高可用性解决方案。
- 延迟监视:Redis集成的延迟监视和报告功能有助于为低延迟工作负载调整Redis实例。
- 基准测试:了解Redis在不同平台上的运行速度。
- Redis发行版:Redis开发周期和版本编号。
嵌入式和物联网
- ARM和Raspberry Pi上的Redis:从Redis 4.0开始,ARM和Raspberry Pi是官方支持的平台。此页面包含常规信息和基准。
- 可在此处找到用于物联网和边缘计算的Redis参考实现。
故障排除
- Redis问题?:虫子?高延迟?其他事宜?使用我们的问题疑难解答页面作为查找更多信息的起点。
Redis集群
- Redis Cluster教程:Redis Cluster的入门介绍和设置指南。
- Redis Cluster规范:Redis Cluster中使用的行为和算法的更正式描述。
其他基于Redis的分布式系统
- Redis CRDT为Redis提供了一种主动-主动地理分布解决方案。
- Roshi是基于Redis的带时间戳事件的大规模CRDT集实现,并在Go中实现。它最初是为SoundCloud流开发的。
在SSD和永久性存储器上进行Redis
技术指标
- Redis设计草案:新提案的设计草案。
- Redis协议规范:如果您正在实施客户端或出于好奇,请学习如何与Redis进行低级通信。
- Redis RDB格式规范和RDB版本历史记录。
- 内部构件:了解有关如何在内部实现Redis的详细信息。
资源资源
用例
Redis Standalone单点模式
单点模式顾名思义就是一个redis节点,这样的方式在开发阶段没有任何问题。
原理简介
这是最简单的 redis 部署方案,所有数据存储和读写操作都在同一个 redis 服务上。
这种方式优点很明显:部署简单,无论是部署成本还是运维成本都很低,本地测试时最常见也是最方便的方式。
但同时缺点也很明显:不能实现高可用,也不能应对高并发场景,也无法轻易水平拓展,数据储存量很容易见顶。
部署实例
单节点模式的部署是最简单的,一下是 Linux 系统下部署单节点 redis 的方法:
# 下载 Redis 二进制安装包:
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
# 解压二进制包
tar –zxvf redis-5.0.4.tar.gz
# 进入解压文件夹并编译二进制文件
cd redis-5.0.4
make
# 安装
cd src
make test
make install
在 make install 和 make test 的时候可能会遇到下面这个问题:
You need tcl 8.5 or newer in order to run the Redis test
make: *** [test] Error 1
这是因为系统中的 TCL 语言版本太低,TCL 语言是一种工具脚本语言,在安装 Redis 的过程中 make test 命令需要用到这个脚本语言,这个时候我们需要升级一下系统中的 TCL 版本:
# 下载一个高于 8.5 版本的 TCL 安装包,比如 8.6.8
wget http://downloads.sourceforge.net/tcl/tcl8.6.8-src.tar.gz
# 解压
tar -zxvf tcl8.6.8-src.tar.gz -C /usr/local/
# 切换到解压后的源码目录
cd /usr/local/tcl8.6.8/unix/
# 编译和安装
sudo ./configure
sudo make
sudo make install
升级 TCL 到 8.5 版本以后,继续执行之前报错的语句,完成 Redis 的安装,安装完成后用 redis-server -v
验证安装是否成功,若成功输出如下版本信息则代表安装成功:
Redis server v=5.0.4
安装成功就可以直接运行了,但是默认配置下是不支持后台运行的,观点命令窗口就会结束 redis 进程,这显然是不行的。所以我们再简单改一下 redis 的配置,让其能够直接后台运行。
# 进入到 redis 的安装目录,编辑 redis.conf
vim /usr/redis/redis-5.0.4/redis.conf
# 将 daemonize no 修改成 daemonize yes (使 redis 服务可以在后台运行)
# 在指定配置下运行redis服务
/usr/local/bin/redis-server /usr/redis/redis-5.0.4/redis.conf
# 查看redis运行情况
ps -ef | grep redis
# 输出
app 21794 1 0 Jan28 ? 03:31:25 ./redis-server *:6379
可以看到 redis 在默认的 6379 端口下运行,配置文件中还有一些可以调整的地方,这里就不一一列举了。那么单节点模式 redis 服务就部署完成了。
开启用户密码验证,日志和后台运行模式请自行研究。
Redis Cluster 集群模式
Scale with Redis Cluster | Docs
本文档是对Redis Cluster的简要介绍,其中没有使用难以理解的分布式系统概念。它提供了有关如何设置集群,测试和操作集群的说明,而没有涉及Redis集群规范中涵盖的细节,而只是从用户的角度描述了系统的行为。
但是,本教程尝试从最终用户的角度提供有关Redis Cluster的可用性和一致性特征的信息,并以一种易于理解的方式进行陈述。
请注意,本教程需要Redis 3.0或更高版本。
如果您计划运行认真的Redis Cluster部署,则建议阅读更正式的规范,即使并非严格要求也是如此。但是,最好从本文档开始,与Redis Cluster一起玩一些时间,然后再阅读规范。
Redis集群101
Redis Cluster提供了一种运行Redis安装的方法,在该安装中,数据会 在多个Redis节点之间自动分片。
Redis Cluster 在分区期间还提供了一定程度的可用性,这实际上是在某些节点出现故障或无法通信时继续操作的能力。但是,如果发生较大故障(例如,大多数主服务器不可用时),群集将停止运行。
因此,实际上,Redis Cluster会带来什么?
- 的能力,自动分割在多个节点之间的数据集。
- 当一部分节点出现故障或无法与集群的其余部分通信时,继续运行的能力。
Redis群集TCP端口
每个Redis群集节点都需要打开两个TCP连接。用于服务客户端的常规Redis TCP端口,例如6379,再加上在数据端口上加上10000所获得的端口,因此在示例中为16379。
第二个高端口用于群集总线,即使用二进制协议的节点到节点通信通道。节点将群集总线用于故障检测,配置更新,故障转移授权等。客户端永远不要尝试与群集总线端口进行通信,而应始终与普通的Redis命令端口进行通信,但是请确保您同时打开防火墙中的两个端口,否则Redis群集节点将无法进行通信。
命令端口和集群总线端口的偏移量是固定的,并且始终为10000。
请注意,对于每个节点,要使Redis群集正常工作,您需要:
- 普通客户端通信端口(通常为6379)用于与客户端通信,以向需要访问群集的所有客户端以及所有其他群集节点(使用客户端端口进行密钥迁移)开放。
- 群集总线端口(客户端端口+ 10000)必须可从所有其他群集节点访问。
如果您没有同时打开两个TCP端口,则您的群集将无法正常工作。
集群总线使用不同的二进制协议进行节点到节点的数据交换,它更适合于使用很少的带宽和处理时间在节点之间交换信息。
Redis集群和Docker
当前,Redis Cluster不支持NATted环境以及在重新映射IP地址或TCP端口的常规环境中。
Docker使用一种称为端口映射的技术:与该程序认为正在使用的端口相比,在Docker容器内运行的程序可能会使用不同的端口公开。为了在同一服务器上同时使用同一端口运行多个容器,这很有用。
为了使Docker与Redis Cluster兼容,您需要使用Docker 的主机联网模式。请检查Docker文档中的--net=host
选项以获取更多信息。
Redis集群数据分片
Redis Cluster不使用一致的哈希,而是使用不同形式的分片,其中每个键从概念上讲都是我们称为哈希槽的一部分。
Redis集群中有16384个哈希槽,要计算给定密钥的哈希槽,我们只需对密钥的CRC16取模16384。
Redis群集中的每个节点都负责哈希槽的子集,因此,例如,您可能有一个包含3个节点的群集,其中:
- 节点A包含从0到5500的哈希槽。
- 节点B包含从5501到11000的哈希槽。
- 节点C包含从11001到16383的哈希槽。
这样可以轻松添加和删除集群中的节点。例如,如果我想添加一个新节点D,则需要将一些哈希槽从节点A,B,C移到D。类似地,如果我想从集群中删除节点A,则只需移动A所服务的哈希槽到B和C。当节点A为空时,我可以将其从群集中完全删除。
因为将哈希槽从一个节点移动到另一个节点不需要停止操作,所以添加和删除节点或更改节点持有的哈希槽的百分比不需要任何停机时间。
只要单个命令执行(或整个事务或Lua脚本执行)中涉及的所有键都属于同一个哈希槽,Redis Cluster就支持多种键操作。用户可以通过使用称为哈希标签的概念来强制多个键成为同一哈希槽的一部分。
哈希标签记录在Redis群集规范中,但要点是,如果密钥中{}括号之间有一个子字符串,则仅对该字符串内的内容进行哈希处理,因此,例如this{foo}key
,another{foo}key
并保证它们在同一哈希槽中,并且可以在带有多个键作为参数的命令中一起使用。
Redis Cluster主从模型
为了在主节点子集出现故障或无法与大多数节点通信时保持可用,Redis Cluster使用主从模型,其中每个哈希槽具有从1(主节点本身)到N个副本(N个) -1个其他从属节点)。
在具有节点A,B,C的示例集群中,如果节点B失败,则集群将无法继续,因为我们不再有办法为5501-11000范围内的哈希槽提供服务。
但是,在创建集群(或稍后)时,我们向每个主节点添加一个从属节点,以便最终集群由作为主节点的A,B,C和作为从属节点的A1,B1,C1组成,如果节点B发生故障,系统将能够继续。
节点B1复制B,并且B失败,群集将把节点B1提升为新的主节点,并将继续正常运行。
但是请注意,如果节点B和B1同时失败,则Redis Cluster无法继续运行。
Redis群集一致性保证
Redis Cluster无法保证强一致性。实际上,这意味着在某些情况下,Redis Cluster可能会丢失系统认可给客户端的写入。
Redis Cluster可能丢失写入的第一个原因是因为它使用异步复制。这意味着在写入期间发生以下情况:
- 您的客户写信给主B。
- 主B向您的客户回复OK。
- 主机B将写操作传播到其从机B1,B2和B3。
如您所见,B在回复客户端之前不会等待B1,B2,B3的确认,因为这会对Redis造成极高的延迟,因此,如果您的客户端写了一些东西,B会确认写,但是在崩溃之前崩溃由于能够将写操作发送到其从属设备,一个从属设备(未接收到写操作)可以被提升为主设备,从而永远丢失写操作。
这与配置为每秒将数据刷新到磁盘的大多数数据库所发生的情况非常相似,因此由于过去使用不涉及分布式系统的传统数据库系统的经验,您已经可以对此进行推理。同样,您可以通过强制数据库在答复客户端之前刷新磁盘上的数据来提高一致性,但这通常会导致性能过低。在Redis Cluster的情况下,这相当于同步复制。
基本上,需要在性能和一致性之间进行权衡。
Redis Cluster在绝对需要时支持通过WAIT命令实现的同步写入,这使得丢失写入的可能性大大降低,但是请注意,即使使用同步复制,Redis Cluster也不实现强一致性:在更复杂的情况下,总是有可能的无法将写操作的从属设备选为主设备的失败情况。
还有另一种值得注意的情况,Redis Cluster将丢失写操作,这种情况发生在网络分区期间,在该分区中,客户端与少数实例(至少包括主实例)隔离。
以我们的6个节点集群为例,该集群由A,B,C,A1,B1,C1组成,具有3个主节点和3个从节点。还有一个客户,我们将其称为Z1。
发生分区后,可能在分区的一侧有A,C,A1,B1,C1,而在另一侧有B和Z1。
Z1仍然能够写入B,它将接受其写入。如果分区在很短的时间内恢复正常,则群集将继续正常运行。但是,如果分区持续的时间足以使B1升级为该分区的多数端的主服务器,则Z1向B发送的写操作将丢失。
请注意,Z1能够发送到B的写入量有一个最大的窗口:如果已经有足够的时间让分区的多数派选举出一个从属服务器为主节点,那么少数派的每个主节点都将停止接受写入操作。
此时间量是Redis Cluster的非常重要的配置指令,称为节点超时。
节点超时结束后,将主节点视为故障节点,并且可以用其副本之一替换该主节点。类似地,在没有主节点能够感知大多数其他主节点的节点超时之后,它进入错误状态并停止接受写操作。
Redis集群配置参数
我们将创建一个示例集群部署。在继续之前,让我们介绍Redis Cluster在redis.conf
文件中引入的配置参数。当您继续阅读时,有些会很明显,有些会更清晰。
- cluster-enabled
<yes/no>
:如果是,则在特定Redis实例中启用Redis Cluster支持。否则,实例将像往常一样作为独立实例启动。 - cluster-config-file
<filename>
:请注意,尽管有此选项的名称,但它不是用户可编辑的配置文件,而是Redis Cluster节点每次发生更改时都会自动持久保存集群配置的文件(状态,基本上是),为了能够在启动时重新阅读它。该文件列出了诸如集群中其他节点之类的东西,它们的状态,持久变量等等。通常,由于收到某些消息,此文件将被重写并刷新到磁盘上。 - cluster-node-timeout
<milliseconds>
:Redis群集节点不可用的最长时间(不将其视为失败)。如果主节点无法访问的时间超过指定的时间量,则其主节点将对其进行故障转移。此参数控制Redis Cluster中的其他重要事项。值得注意的是,在指定的时间内无法到达大多数主节点的每个节点都将停止接受查询。 - cluster-slave-validity-factor
<factor>
:如果设置为零,则从服务器将始终尝试对主服务器进行故障转移,而不管主服务器和从服务器之间的链接保持断开状态的时间长短。如果该值为正,则将最大断开时间计算为节点超时值乘以此选项提供的因子,如果节点是从节点,则如果断开主链接的时间超过指定的时间,它将不会尝试启动故障转移。例如,如果节点超时设置为5秒,而有效性因子设置为10,则从服务器与主服务器断开连接超过50秒将不会尝试对其主服务器进行故障转移。请注意,如果没有从属可以对其进行故障转移,则任何非零的值都可能导致Redis群集在主服务器发生故障后不可用。在这种情况下,只有当原始主服务器重新加入集群后,集群才会恢复可用。 - cluster-migration-barrier
<count>
:主机将保持连接的最小数量的从机,以便另一个从机迁移到不再被任何从机覆盖的主机。有关更多信息,请参见本教程中有关副本迁移的相应部分。 - cluster-require-full-coverage
<yes/no>
:如果设置为yes,默认情况下,如果某个节点没有覆盖一定比例的密钥空间,集群将停止接受写入。如果该选项设置为no,即使仅可以处理有关密钥子集的请求,群集仍将提供查询。 - cluster-allow-reads-when-down
<yes/no>
:如果将其设置为no(默认情况下为默认值