一、Redis的可执行文件
当我们安装完Redis之后,src和/usr/local/bin目录下提供了下面这些可执行程序,我们称之为Redis Shell:
redis-server | Redis服务器 |
redis-cli | Redis命令行客户端 |
redis-benchmark | Redis性能测试工具 |
redis-check-aof | Redis AOF持久化文件检测和AOF文件修复工具 |
redis-check-dump | Redis RDB持久化文件检测和文件检查工具 |
redis-sentinel | Sentinel服务器(Redis2.8版本之后) |
二、Redis默认配置文件
Redis的默认配置文件:
在下载的redis源码包根目录下有一个名为redis.conf的配置文件,这个配置文件中的参数是redis服务器启动的默认参数(备注:但是redis-server启动不是使用这个配置文件)
如果你想自己设置配置参数,那么可以拷贝这个配置文件然后修改,在redis-server启动时指定配置文件的路径
相对于很多大型存储系统,Redis的配置不是很多,到了Redis3.0之后有60多个
①单机模式下的配置参数
总体配置:下图是Redis的一些总体配置,例如端口、日志、数据库等
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程daemonize no2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定pidfile /var/run/redis.pid3. 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字port 63794. 绑定的主机地址bind 127.0.0.15.当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能timeout 3006. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verboseloglevel verbose7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/nulllogfile stdout8. 设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库iddatabases 169. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合save <seconds> <changes>Redis默认配置文件中提供了三个条件:save 900 1save 300 10save 60 10000分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大rdbcompression yes11. 指定本地数据库文件名,默认值为dump.rdbdbfilename dump.rdb12. 指定本地数据库存放目录dir ./13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步slaveof <masterip> <masterport>14. 当master服务设置了密码保护时,slav服务连接master的密码masterauth <master-password>15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭requirepass foobared16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息maxclients 12817. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区maxmemory <bytes>18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为noappendonly no19. 指定更新日志文件名,默认为appendonly.aofappendfilename appendonly.aof20. 指定更新日志条件,共有3个可选值: no:表示等操作系统进行数据缓存同步到磁盘(快) always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)everysec:表示每秒同步一次(折衷,默认值)appendfsync everysec21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)vm-enabled no22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享vm-swap-file /tmp/redis.swap23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0vm-max-memory 024. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值vm-page-size 3225. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。vm-pages 13421772826. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4vm-max-threads 427. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启glueoutputbuf yes 28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法 hash-max-zipmap-entries 64 hash-max-zipmap-value 512 29. 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)activerehashing yes 30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件 include /path/to/local.conf
AOF相关配置参数说明:
本文主要描述了aof中的相关参数以及为什么这样是可以足够安全的。appendonly:开启aof特性,这个控制是否启用aof.appendfilename:写入文件的文件名。开启aof之后,每条命令(除读之外的命令),均会写入到文件中,这里即实际写入的文件.appendfsync:写入策略,默认值everysec,每秒写一次(调用flush)。另外两个值,always | no,分别表示每次redis写命令之外就写文件,和由操作系统保证。always对硬盘压力大,everysec是一个平衡值,no对硬盘压力最小,但调度由系统控制,丢失数据风险最大.no-appendfsync-on-rewrite:是否在后台写时同步单写,默认值no(表示需要同步).这里的后台写,表示后台正在重写文件(包括bgsave和bgrewriteaof.bgrewriteaof网上很多资料都没有涉及到。其实关掉bgsave之后,主要的即是aof重写文件了).no表示新的主进程的set操作会被阻塞掉,而yes表示新的主进程的set不会被阻塞,待整个后台写完成之后再将这部分set操作同步到aof文件中。但这可能会存在数据丢失的风险(机率很小),如果对性能有要求,可以设置为yes,仅在后台写时会异步处理命令.auto-aof-rewrite-percentage:aof文件增长比例,指当前aof文件比上次重写的增长比例大小。aof重写即在aof文件在一定大小之后,重新将整个内存写到aof文件当中,以反映最新的状态(相当于bgsave)。这样就避免了,aof文件过大而实际内存数据小的问题(频繁修改数据问题).auto-aof-rewrite-min-size:aof文件重写最小的文件大小,即最开始aof文件必须要达到这个文件时才触发,后面的每次重写就不会根据这个变量了(根据上一次重写完成之后的大小).此变量仅初始化启动redis有效.如果是redis恢复时,则lastSize等于初始aof文件大小.aof-load-truncated:指redis在恢复时,会忽略最后一条可能存在问题的指令。默认值yes。即在aof写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes会log并继续,而no会直接恢复失败.Linux内核参数:另外,与aof重写相关的一个linux内核参数即是 overcommit_memory。即在进行重写时,如何分配子进程内存的问题。(重写是后台重写,会分配子进程).默认值为0,建立设置为1,以保证 子进程内存能够分配成功(即使用copyOnWrite内存分配策略,在没有set命令时会和主进程使用同一份内存),并且不会判断当前内存是否够用.
RDB相关配置:
save 900 1 # 时间策略 save 300 10 # 时间策略 save 60 10000 # 时间策略 dbfilename dump.rdb #文件名称 dir /home/work/app/redis/data/ #文件保存路径 stop-writes-on-bgsave-error yes # 如果持久化出错,主进程是否停止写入 rdbcompression yes # 是否压缩 rdbchecksum yes # 导入时是否检查
那么为什么需要配置这么多条规则呢?
因为Redis每个时段的读写请求肯定不是均衡的,为了平衡性能与数据安全,我们可以自由定制什么情况下触发备份。
所以这里就是根据自身Redis写入情况来进行合理配置。
stop-writes-on-bgsave-error yes :
这个配置也是非常重要的一项配置,这是当备份进程出错时,主进程就停止接受新的写入操作,是为了保护持久化的数据一致性问题。
如果自己的业务有完善的监控系统,可以禁止此项配置, 否则请开启。
rdbcompression yes :
关于压缩的配置 ,建议没有必要开启,毕竟Redis本身就属于CPU密集型服务器,再开启压缩会带来更多的CPU消耗,相比硬盘成本,CPU更值钱。
当然如果你想要禁用RDB配置,也是非常容易的,只需要在save的最后一行写上:save ""
慢查询配置:
slowlog-log-slower-than选项:
指定执行时间超过多少微秒(1秒等于1000 000微秒)的命令请求会被记录到日志上
举个例子,如果这个选项的值为100,那么执行时间超过100微秒的命令就会被记录到慢查询日志
提示:如果slowlog-log-slower-than=0会记录所有的命令,slowlog-log-slowerthan<0对于任何命令都不会进行记录
slowlog-max-len选项:
指定服务器最多保存多少条慢查询日志
慢查询日志数量的溢出
Redis使用了一个列表来存储慢查询日志,服务器使用先进先出的方式保存多条慢查询日志,当服务器存储的慢查询日志数量等于slowlog-max-len选项的值时,服务器在添加一条新的慢查询日志之前,会先将最旧的一条慢查询日志删除
举个例子,如果服务器slowlog-max-len的值为100,并且假设服务器已经储存了100条慢查询日志,那么如果服务器打算添加一条新日志的话,它就必须先删除目前保存的最旧的那条日志,然后再添加新日志
配置参数的设置
如果要Redis将配置持久化到本地配置文件,需要执行config rewrite命令
config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
可以使用CONFIG命令设置配置参数的值
数据结构优化配置:
下图是Redis数据结构优化的相关配置 :
自从Redis 2.2之后,很多数据类型都可以通过特殊编码的方式来进行存储空间的优化。其中,Hash、List和由Integer组成的Sets都可以通过该方式来优化存储结构,以便占用更少的空间,在有些情况下,可以省去9/10的空间。 这些特殊编码对于Redis的使用而言是完全透明的,事实上,它只是CPU和内存之间的一个交易而言。如果内存使用率方面高一些,那么在操作数据时消耗的CPU自然要多一些,反之亦然。在Redis中提供了一组配置参数用于设置与特殊编码相关的各种阈值,如:#如果Hash中字段的数量小于参数值,Redis将对该Key的Hash Value采用特殊编码。hash-max-zipmap-entries 64#如果Hash中各个字段的最大长度不超过512字节,Redis也将对该Key的Hash Value采用特殊编码方式。hash-max-zipmap-value 512#下面两个参数的含义基本等同于上面两个和Hash相关的参数,只是作用的对象类型为List。list-max-ziplist-entries 512list-max-ziplist-value 64#如果set中整型元素的数量不超过512时,Redis将会采用该特殊编码。set-max-intset-entries 512倘若某个已经被编码的值再经过修改之后超过了配置信息中的最大限制,那么Redis会自动将其转换为正常编码格式,这一操作是非常快速的,但是如果反过来操作,将一个正常编码的较大值转换为特殊编码,Redis的建议是,在正式做之前最好先简单测试一下转换效率,因为这样的转换往往是非常低效的。
主从复制相关配置:
实现Redis的主从复制配置比较简单,而且容易明白。
下图是要配置的主从复制结构图:
1.说明
Redis主从复制中一个主服务可以有多个从服务,一个从服务可以有多个从服务。
配置比较简单,只需要更改redis.conf文件中的slaveof参数配置即可。
slaveof参数的格式如:slaveof <masterip> <masterport>
如果master服务器设置有密码则需要配置masterauth参数。
masterauth参数格式如:masterauth <master-password>
2.配置主从服务器
如上图可见master和slave1,slave2,slave3的服务器的端口的IP。
master :port 6379 requirepass redis slave1 : port 6479 slaveof 127.0.0.1 6379 masterauth redis requirepass redis slave2 : port 6579 slaveof 127.0.0.1 6479 masterauth redis requirepass redis slave3 : port 6679 slaveof 127.0.0.1 6379 masterauth redis requirepass redis
需要注意的是如果服务器中为设置requirepass参数,则从服务中不需要设置masterauth参数。
②Sentinel配置说明和分析
Redis的主从模式下,主节点一旦发生故障不能提供服务,需要人 工干预,将从节点晋升为主节点,同时还需要修改客户端配置。 对于很多应用场景这种方式无法接受。
Redis从 2.8发布了一个稳定版本的Redis Sentinel 。当前版本的 Sentinel称为Sentinel 2。它是使用更强大和更简单的预测算法来重 写初始Sentinel实现。(Redis2.6版本提供Sentinel 1版本,但是有 一些问题)
Sentinel(哨兵)架构解决了redis主从人工干预的问题。
Redis Sentinel是redis的高可用实现方案,在实际生产环境中,对 提高整个系统可用性是非常有帮助的。
Redis Sentinel是一个分布式系统,Redis Sentinel为Redis提供高可用性。可以在没有人为干预的情况下 阻止某种类型的故障。
可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来 接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故 障迁移, 以及选择哪个从服务器作为新的主服务器。
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance) 该系统执行以下三个任务:
监控(Monitoring): Sentinel 会不断地定期检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automaticfailover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中 一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客 户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主 服务器代替失效服务器
以下是一些修改sentinel配置的命令:SENTINEL MONITOR <name> <ip> <port> <quorum>这个命令告诉sentinel去监听一个新的masterSENTINEL REMOVE <name> 命令sentinel放弃对某个master的监听SENTINEL SET <name> <option> <value> 这个命令很像Redis的CONFIG SET命令,用来改变指定master的配置。
③Cluster配置说明和分析
Cluster节点是特殊的Redis节点,有几个特殊的配置,如下图所示
CONFIG SET、CONFIG GET命令
我们可以在不重新启动Redis的情况下动态修改部分Redis配置(注:并不是所有的配置都支持CONFIG SET命令,具体见上图)
redis>CONFIG SET loglevel warning
我们也可以通过CONFIG GET来获取一个配置的值:1)是配置选项名称,2)是选项值
requirepass配置参数
该参数用于权限控制。当设置了这个参数之后,客户端连接时就需要输入密码才可以连接到服务器
演示案例
在配置文件中加入该参数,密码为“123456”
requirepass 123456
重启redis服务器,然后再使用上面的配置文件启动redis(此处我们的redis以守护进程运行的)
此时我们使用redis-cli虽然可以连接上服务端,但是输入命令都无权限,需要认证
此时我们需要输入auth命令和密码进行认证,认证完之后就可以进行操作了
当然,我们也可以通过redis-cli的“-a”参数指定连接时的密码,这样就不需要输入auth命令进行认证了。备注:不建议这样做,因为密码可能会外漏
redis-cli -a 123456
多线程相关的配置参数
在redis 6.0之后支持多线程了
io-threads-do-reads配置参数:要开启多线程,那么需要在配置文件中将该参数设置为yes
io-threads-do-reads on;
io-threads配置参数:该参数用来设置线程的数量
io-threads 4;
线程数的设置建议:官方有一个建议,4 核的机器建议设置为 2 或 3 个线程,8 核的建议设置为 6 个线程,线程数一定要小于机器核数
bind配置参数
该参数代表redis服务端接受从哪些网络通道传来的网络流量
例如,下面服务端只接受127.0.0.1和172.17.0.14网段的网络流量
bind 127.0.0.1 172.17.0.14
备注:Redis3.0中bind默认值为””,也就是不限制网卡的访问,但是在Redis3.2 中必须显示的配置bind 0.0.0.0才可以达到这种效果
protected-mode配置参数
Redis3.2提供了protected-mode配置(默认开启)
功能:如果当前Redis没有配置密码,没有配置bind,那么只允许来自本机的访问,也就是相当于配置了bind 127.0.0.1
演示案例:下面redis服务端开启了该配置参数,且配置文件中没有配置密码,也没有配置bind,当外网访问时显示不能访问
三、Redis服务端的启动
有三种方法启动Redis:默认配置启动、运行配置启动、配置文件启动
①默认配置启动
直接运行redis-server即可启动Redis:
sudo redis-server
这种方法会使用Redis的默认配置文件来启动Redis,例如Redis默认配置文件中指定Redis的端口号为6379、当前版本为6.0.1
实际生产环境中一般不使用这种方法来启动Redis,因为无法自定义配置
②运行配置启动
我们在运行时可以指定配置名和值(可以是多对),没有配置的将仍然使用默认配置
例如,下面以6379端口启动Redis,其他参数仍使用默认值
sudo redis-server --port 6379
这种方法也不建议使用,因为如果修改的配置较多的话那么比较麻烦,并且这种参数不能保存到文件中
③指定配置文件启动
将配置写到指定文件里,例如我们将配置写到了/opt/redis/redis.conf,那么可以执行下面的命令启动redis:
sudo redis-server /opt/redis/redis.conf
比较建议使用这种方式启动Redis
redis有60多个配置参数,在上面介绍了一些,后面文章还会介绍更多。下面列出了一些重要配置参数:
参数 说明 daemonize 是否以守护进程模式运行Redis pidfile 设置Redis的PID文件位置 logfile 日志文件位置 port 设置Redis监听的端口号 dir Redis工作目录(存放持久化文件和日志文件)
我们也可以在启动时同时指定配合文件和配置选项,那么命令行的配置选项就会覆盖配置文件中的参数。例如:
redis-server 配置文件名.conf --loglevel warning
四、Redis服务端的关闭
shutdown命令
正确停止Redis的方式应该是向Redis发送SHUTDOWN命令,方法为:
当Redis收到SHUTDOWN命令后,会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出
Redis可以妥善处理SIGTERM信号,所以使用kill Redis进程的PID也可以正常结束Redis,效果与发送SHUTDOWN命令一样
①如果客户端还没有与服务端进行连接,那么可以执行在命令行输入下面的命令来关闭服务端:
redis-cli SHUTDOWN
②如果客户端工具已经连接入服务端,那么直接输入SHUTDOWN即可:
shutdown还有一个参数,代表是否在关闭Redis前,生成持久化文件
redis-cli shutdown nosave|save
考虑到Redis有可能正在将内存中的数据同步到硬盘中,强行终止Redis进程可能会导致数据丢失,因此不建议使用kill-9强制杀死Redis服务,不但不会做持久化操作,还会造成缓冲区等资源不能被优雅关闭,极端情况会造 成AOF和复制丢失数据的情况
五、Redis服务端的重启
使用软件包编译安装的redis不支持重启操作,只能通过redis-cli进行SHUTDOWN关机然后再重新开启服务端
但是如果使用apt-get或yum形式安装的redis支持重启(见文章最后)
六、连接到Redis服务端
使用redis-cli可以连接到redis服务端,有两种连接方式
①交互式连接
第一种是交互式方式,连接之后不会退出redis-cli命令行
例如,下面连接到IP为127.0.0.1、端口为6379的redis服务端
redis-cli -h 127.0.0.1 -p 6379
可以不写-h和-p参数,它们的默认值分别为127.0.0.1和6379
②命令方式连接
第二种是命令方式连接,只连接一次就断开
例如,下面连接的时候获取一次玩家的数据就退出
关于redis-cli在后面会详细介绍
七、redis设置允许外网连接
设置方法如下:
如果没有为redis设置密码(也就是没有设置requirepass配置参数),那么需要将protected-mode配置参数更改为no
如果你的redis设置了密码(也就是设置了requirepass配置参数),那么不需要更改protected-mode配置参数
第一步:注释掉配置文件中的bind参数
第二步:如果你的bind参数被注释了,那么还要分为以下两种情况:
bind 0.0.0.0
# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
# "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode no
八、软件包安装的redis的开机、关闭、重启
如果是使用apt-get或yum形式安装的redis,那么支持下面的几种方式
sudo /etc/init.d/redis-server stop #关机
sudo /etc/init.d/redis-server start #启动
sudo /etc/init.d/redis-server restart #重启