忙碌是一种幸福,让我们没时间体会痛苦;奔波是一种快乐,让我们真实地感受生活;疲惫是一种享受,让我们无暇空虚。这几句话就能简单概括我最近的工作和生活。
好多小伙伴都来私信“催更”,今天它来了!为了表达阿Q的歉意,特赠送「亿级流量Java高并发与网络编程实战」一本,规则见文末。
在往期的文章中我们已经对Redis
的概念和基本命令进行了讲解,今天我们来看下它的配置文件,Redis
的配置文件在我们的开发和实际应用中起着非常重要的作用。
我们可以在安装目录下找到redis.conf
配置文件,通过vim
命令进行查看,为了防止配置文件进行更改,大家在使用前一定要备份一下!
本文Redis
的版本为5.0.7
UNITS
代码语言:javascript复制1k => 1000 bytes
1kb => 1024 bytes
1m => 1000000 bytes
1mb => 1024*1024 bytes
1g => 1000000000 bytes
1gb => 1024*1024*1024 bytes
❝单位不区分大小写,只支持bytes ❞
INCLUDES
和structs2
配置文件类似,可以通过includes
包含。redis.conf
可以作为总闸,包含其他。
include /path/to/local.conf
include /path/to/other.conf
MODULES
代码语言:javascript复制loadmodule /path/to/my_module.so
loadmodule /path/to/other_module.so
Redis
可以通过loadmodule
选项在启动时加载模块,若服务端无法加载模块,服务端会停止。可以通过多个loadmodule
选项加载多个模块。
NETWORK
- 「bind 127.0.0.1」:默认情况下,如果未指定“bind”配置指令,
Redis
将侦听服务器上所有可用网络接口的连接。
可以使用“bind”配置指令,后跟一个或多个IP地址,只侦听一个或多个选定接口。「例如:」bind 192.168.1.100 10.0.0.1
当设置多个bind
地址后,Redis
内部会维护多个Socket
,每个Socket
用于一个network interface
。
- 「protected-mode yes」:此选项默认开启。
当Redis
服务端未使用bind
选项显式指定要监听的network interface
,并且未设置密码,Redis
服务端只会接受来自127.0.0.1
和::1
的客户端以及Unix
域的Socket
进行连接。
- 「port 6379」:用于设置
Redis
监听的TCP
端口,默认为6379,设置为0表示不监听TCP
端口 - 「timeout 0」:空闲多少秒之后关闭连接,“0”表示不关闭
- 「tcp-keepalive 300」:单位为秒,如果为0,则不会进行
keepalive
检测,建议设置成60 - 「tcp-backlog 511」:设置
tcp
的backlog
,backlog
其实是一个连接队列。
❝
backlog
队列总和 = 未完成三次握手队列 已经完成三次握手队列 ❞
在高并发环境下需要一个高backlog
值来避免慢客户端连接问题。
「注意」:Linux
内核会将这个值减小到/proc/sys/net/core/somaxconn
的值,所以需要确认增大somaxconn
和tcp_max_syn_backlog
两个值来达到想要的效果。
GENERAL
daemonize
Redis
采用的是单进程多线程的模式,daemonize
是用来指定redis
是否要用守护线程的方式启动。默认情况下,Redis
不作为守护进程运行。如果需要,请使用“是”。
#daemonize no
//当前界面将进入redis的命令行界面,
exit强制退出或者关闭连接工具(putty,
xshell等)都会导致redis进程退出。
daemonize yes
//代表开启守护进程模式。在该模式下,
redis 会在后台运行,并将进程 pid 号写入
至 redis.conf 选项 pidfile 设置的文件中,
此时 redis 将一直运行,除非手动kill该进程。
supervised no
当你通过upstart
或者systemd
运行Redis
时,Redis
可以和你的supervision tree
进行交互,可选的选项为:
- no 无交互(默认)
- upstart 通过向
Redis
发送SIGSTOP
信号来通知upstart
- systemd 通过向
$NOTIFY_SOCKET
写入READY=1
来通知systemd
- auto 通过是否设置了
UPSTART_JOB
或者NOTIFY_SOCKET
环境变量来决定选项为upstart
或者systemd
pidfile
代码语言:javascript复制pidfile /var/run/redis_6379.pid //进程pid文件
loglevel notice
指定服务器日志级别:从上到下依次减少
debug
:大量信息,对开发/测试有用verbose
:许多很少有用的信息,但不像调试级别那样混乱notice
:适度冗长,可能是生产中需要的内容warning
:只记录非常重要/关键的消息
logfile
代码语言:javascript复制logfile ""
日志的名字,如果为空,redis
给控制台标准输出,如果配置为守护进程方式运行,且设置了logfile
为stdout
,则日志将会发送给/dev/null
database
代码语言:javascript复制databases 16
系统默认的库16个,默认使用0库
syslog
syslog-enabled no
:是否把日志输出到syslog
中,系统日志默认是关着syslog-ident redis
:指定syslog
里的日志标志设备以redis
开头syslog-facility local0
:指定syslog
设备,值可以是USER
或LOCAL0-LOCAL7
,默认使用local0
Security (安全)
代码语言:javascript复制requirepass 12345!@#
设置redis
连接密码,如果配置了连接密码,客户端在连接redis
时需要通过Auth <password>
命令提供密码,默认关闭。
如果设置完密码,ping
就失败了,提示“NoAuth Authentication required”,加上auth 密码
就通了。
「要求必须auth password 在任何命令之前」
❝
Redis
一般做的是缓存,不是安全,而且系统会认为Linux
是在安全的环境下。 ❞
CLIENTS
maxclients 10000
:最大连接数
设置redis
同时可以与多少个客户端进行连接。默认情况下为10000
个客户端。
当你无法设置进程文件句柄限制时,redis
会设置为当前的文件句柄限制值减去32
,因为redis
会为自身内部处理逻辑留一些句柄出来。
如果达到了此限制,redis
则会拒绝新的连接请求,并且向这些连接请求方发出「max number of clients reached」以作回应。
MEMORY MANAGEMENT
设置redis
可以使用的内存量。一旦到达内存使用上限,redis
将会试图移除内部数据,移除规则可以通过maxmemory-policy
来指定。
如果redis
无法根据移除规则来移除内存中的数据,或者设置了「不允许移除」,那么redis
则会针对那些需要申请内存的指令返回错误信息,比如SET
、LPUSH
等。但是对于无内存申请的指令,仍然会正常响应,比如GET
等。
如果你的redis
是主redis
(说明你的redis
有从redis
),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素。
最大缓存
代码语言:javascript复制#maxmemory <bytes>
maxmemory 128MB
设置maxmemory
和相对应的回收策略算法,设置最好为物理内存的「3/4」,或者比例更小,因为redis
复制数据等其他服务时,也是需要缓存的。以防缓存数据过大致使redis
崩溃,造成系统出错不可用。
牺牲一部分缓存数据,保存整体系统可用性。redis
新的内存机制,会把key
放在内存,value
存放在swap
区。
此配置需要和「maxmemory-policy」配合使用,当redis
中内存数据达到maxmemory
时,触发「清除策略」。在「内存不足」时,任何write
操作(比如set
,lpush
等)都会触发「清除策略」的执行。
实际环境
建议redis
的所有物理机器的硬件配置保持一致(内存一致),同时确保master/replica
中「maxmemory policy」配置一致。
内存满时
如果还接收到set
命令,redis
将先尝试剔除设置过expire
信息的key
,而不管该key
的过期时间有没有到达。
在删除时,将按照过期时间进行删除,最早将要被过期的key
将最先被删除。如果带有expire
信息的key
都删光了,内存还不够用,那么将返回错误。这样,redis
将不再接收写请求,只接收get
请求。
❝
maxmemory
的设置比较适合于把redis
当作于类似memcached
的缓存来使用。 ❞
最大缓存策略
「maxmemory-policy」:
- volatile-lru:使用
LRU
(最近最少使用)算法移除key
,只对设置了过期时间的键 - allkeys-lru:使用
LRU
算法移除key
(所有key
) - volatile-lfu:对过期键使用 LFU(最不经常使用)近似算法
- allkeys-lfu:对所有键使用 LFU 近似算法
- volatile-random:在过期集合中移除随机的
key
,只对设置了过期时间的键 - allkeys-random:移除随机的
key
- volatile-ttl:移除那些
TTL
值最小的key
,即那些最近要过期的key
- noeviction:不进行移除。针对写操作,只是返回错误信息(默认)(去公司观察维度,不应该选择这个)
❝
LRU
算法、LFU
算法或者TTL
算法都是不是很精确算法,而是个近似算法。 ❞
「使用策略规则:」
- 如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用
allkeys-lru
。 - 如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用
allkeys-random
。
样本数量
设置样本数量,上边提到的算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小。
代码语言:javascript复制maxmemory-samples 5
默认值是 5,也就是说Redis
随机挑出5个键,然后选出一个最符合条件的。对LRU
来说5是比较合适的。10已经很接近于真正的LRU
,但会消耗更多的CPU
。3会更快但没有那么精确。
副本忽略最大内存
代码语言:javascript复制replica-ignore-maxmemory yes
从Redis 5
开始,默认情况下,replica
节点会忽略maxmemory
设置(除非在发生failover
后,此节点被提升为master
节点)。
这意味着只有master
才会执行过期删除策略,并且master
在删除键之后会对replica
发送DEL
命令。
这个行为保证了master
和replicas
的一致性,并且这通常也是你需要的,但是若你的replica
节点是可写的,或者你希望replica
节点有不同的内存配置,并且你确保所有到replica
写操作都幂等的,那么你可以修改这个默认的行为 (请确保你明白你在做什么)。
「注意」默认情况下replica
节点不会执行过期策略,它有可能使用了超过maxmemory
设定的值的内存。因此你需要监控replicas
节点所在的机器并且确保在master
节点到达配置的maxmemory
大小时,replicas
节点不会超过物理内存的大小。
今天我们就先说到这了,至于配置文件中关于主从复制和持久化部分我们将在后续的内容进行讲解。
赠书活动
《亿级流量Java高并发与网络编程实战》系统全面的介绍了开发人员必学的知识,如JVM
、网络编程、NIO等知识,让开发人员系统地掌握JAVA高并发与网络编程知识。
「推荐理由」
- 全面。本书从并发的底层核心技术、互联网应用框架、数据处理等三部分对高并发系列技术做了系统讲解。
- 实用。本书以实战化训练为宗旨,用详尽且经典的案例阐述了Java大数据及高级编程中的重点、难点。书中案例由真实项目演化而来,既体现了所述知识点的精华,又屏蔽了无关技术的干扰。
- 案例完整。案例都是以“理论讲解 环境搭建 完整代码及分析 运行截图”这种完善的结构进行讲解,考虑到了读者可能会遇到的各种问题。