简单介绍
Redis:开源、免费、非关系型数据库、K-V数据库、内存数据库,支持持久化、事务和备份,集群(支持16个库)等高可用功能。并且性能极高(可以达到100000+的QPS),易扩展,丰富的数据类型,所有操作都是单线程,原子性的。
NOSQL:非关系型数据库,数据与数据之间没有关联关系。就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题
类型
-
键值(key-value)存储数据库
-
列存储数据库:键仍然存在,但是指向了多个列,HBase (eg:博客平台(标签和文章),日志)
-
文档型数据库 MongoDb (eg:淘宝商品的评价)
-
图形数据库 Neo4j (eg:好友列表)
扩展:
MongoDB是一个基于分布式文件存储的数据库。有C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系型数据库和非关系型数据库之间的产品,是非关系数据库当中功能最丰富,最像关系型数据库的。
文档(document)是MongoDB中数据的基本单元,非常类似于关系型数据库系统中的行(但是比行要复杂的多); 集合(collection)就是一组文档,如果说MongoDB中的文档类似于关系型数据库中的行,那么集合就如同表;
使用场景:
-
数据模型比较简单
-
需要灵活更强的IT系统
-
对数据库性能要求比较高
-
不需要高度的数据一致性
-
对于给定的key,比较容易映射复杂值的环境
SQL:关系型数据库,表与表之间建立关联关系
redis的安装
#拉取镜像
docker pull redis
#挂载数据卷并运行容器
docker run -p 6379:6379 --name redis -v /root/redis/data:/data -v /root/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes --requirepass "xxx"
为什么使用NOSQL
单机 MySQL 的美好时代
在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付。 在那个时候,更多的都是静态网页,动态交互类型的网站不多。
DAL : Data Access Layer(数据访问层 – Hibernate,MyBatis)
上述架构下,我们来看看数据存储的瓶颈
是什么?
数据量的总大小一个机器放不下时。
数据的索引(B+ Tree)一个机器的内存放不下时。
访问量(读写混合)一个实例不能承受。
如果满足了上述1 or 3个时,只能对数据库的整体架构进行重构。
Memcached(缓存)+MySQL+垂直拆分
后来,随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性能。程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。开始比较流行的是通过文件缓存来缓解数据库压力,但是当访问量继续增大的时候,多台web机器通过文件缓存不能共享,大量的小文件缓存也带了了比较高的IO压力。在这个时候,Memcached就自然的成为一个非常时尚的技术产品。
Memcached作为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务,在Memcached服务器上,又发展了根据hash算法来进行多台Memcached缓存服务的扩展,然后又出现了一致性hash来解决增加或减少缓存服务器导致重新hash带来的大量缓存失效的弊端。
Mysql主从读写分离
由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配了。
分库分表+水平拆分+mysql集群
在Memcached的高速缓存,MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,由于MyISAM在写数据的时候会使用表锁,在高并发写数据的情况下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。
ps:这就是为什么 MySQL 在 5.6 版本之后使用 InnoDB 做为默认存储引擎的原因 – MyISAM 写会锁表,InnoDB 有行锁,,并且是事务优先,发生冲突的几率低,并发性能高。
注意锁的几个概念:行锁和表锁,读锁和写锁,乐观锁和悲观锁,还有一个间隙锁
详情请看锁的介绍
四种NoSQL对比
3V+3高
ACID
事务是由一组SQL语句组成的逻辑处理单元,事务具有4属性,通常称为事务的ACID属性。
-
原子性
(Actomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。 -
一致性
(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以操持完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。eg:有3个人进行转账操作,为了保证一致性(即3个人 的账号金额总数不变),那在我写代码的时候,如果写了代码:A=A-5000;此时数据时不一致的。那就必须要写上,B=B+5000,或者是C=C+5000,这样的代码才能保证了数据库的一致性状态。
-
隔离性
(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。具体看下面的几个隔离级别和并发问题。 -
持久性
(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持
CAP
C:consistency,数据在多个副本中能保持一致的状态。
A:Availability,整个系统在任何时刻都能提供可用的服务,通常达到99.99%四个九可以称为高可用
P:Partition tolerance,分区容错性,在分布式中,由于网络的原因无法避免有时候出现数据不一致的情况,系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择,换句话说,系统可以跨网络分区线性的伸缩和扩展。
CAP理论的核心:一个分布式系统不可能同时
很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个
。
-
CA:单点集群,满足一致性,可用性的系统,通常在可扩展上不太强大。应用:传统的Oracle数据库
-
CP:满足一致性,分区容错性的系统,通常性能不是特别高。应用:Redis,MongoDB,银行
-
AP:满足可用性,分区容错性,通常可能对一致性要求低一些。应用:大多数网站架构的选择
CAP理论就是说在分布式存储系统中,最多只能实现上面的两个。而由于当前的网络硬件肯定会出现延迟丢包等问题。所以
分区容忍性是我们必须需要实现的
所以我们只能在一致性和高可用之间进行权衡,没有NoSQL系统能同时保证三点。为什么呢?
为何CAP三者不可兼得
现在我们就来证明一下,为什么不能同时满足三个特性?
假设有两台服务器,一台放着应用A和数据库V,一台放着应用B和数据库V,他们之间的网络可以互通,也就相当于分布式系统的两个部分。
在满足一致性的时候,两台服务器 N1和N2,一开始两台服务器的数据是一样的,DB0=DB0。在满足可用性的时候,用户不管是请求N1或者N2,都会得到立即响应。在满足分区容错性的情况下,N1和N2有任何一方宕机,或者网络不通的时候,都不会影响N1和N2彼此之间的正常运作。
当用户通过N1中的A应用请求数据更新到服务器DB0后,这时N1中的服务器DB0变为DB1,通过分布式系统的数据同步更新操作,N2服务器中的数据库V0也更新为了DB1,这时,用户通过B向数据库发起请求得到的数据就是即时更新后的数据DB1。
上面是正常运作的情况,但分布式系统中,最大的问题就是网络传输问题,现在假设一种极端情况,N1和N2之间的网络断开了,但我们仍要支持这种网络异常,也就是满足分区容错性,那么这样能不能同时满足一致性和可用性呢?
假设N1和N2之间通信的时候网络突然出现故障,有用户向N1发送数据更新请求,那N1中的数据DB0将被更新为DB1,由于网络是断开的,N2中的数据库仍旧是DB0;
如果这个时候,有用户向N2发送数据读取请求,由于数据还没有进行同步,应用程序没办法立即给用户返回最新的数据DB1,怎么办呢?有二种选择,第一,牺牲数据一致性,响应旧的数据DB0给用户;第二,牺牲可用性,阻塞等待,直到网络连接恢复,数据更新操作完成之后,再给用户响应最新的数据DB1。
上面的过程比较简单,但也说明了要满足分区容错性的分布式系统,只能在一致性和可用性两者中,选择其中一个。也就是说分布式系统不可能同时满足三个特性。这就需要我们在搭建系统时进行取舍了。
Base
Base就是为了解决关系型数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。
Base其实是下面三个术语的缩写:
-
基本可用(Basically Available)
-
软状态(Soft state)状态可以有一段时间不同步
-
最终一致(Eventually consistent)最终数据是一致的就可以了,而不是时时保持强一致
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法。
以案例转账为例,我们把用户A给用户B转账分成四个阶段,第一个阶段用户A准备转账,第二个阶段从用户A账户扣减余额,第三个阶段对用户B增加余额,第四个阶段完成转账。系统需要记录操作过程中每一步骤的状态,一旦系统出现故障,系统能够自动发现没有完成的任务,然后,根据任务所处的状态,继续执行任务,最终完成任务,达到一致的最终状态。
在实际应用中,上面这个过程通常是通过持久化执行任务的状态和环境信息,一旦出现问题,定时任务会捞取未执行完的任务,继续未执行完的任务,直到执行完成为止,或者取消已经完成的部分操作回到原始状态。这种方法在任务完成每个阶段的时候,都要更新数据库中任务的状态,这在大规模高并发系统中不会有太好的性能,一个更好的办法是用Write-Ahead Log(写前日志),这和数据库的Bin Log(操作日志)相似,在做每一个操作步骤,都先写入日志,如果操作遇到问题而停止的时候,可以读取日志按照步骤进行恢复,并且继续执行未完成的工作,最后达到一致。写前日志可以利用机械硬盘的追加写而达到较好性能,因此,这是一种专业化的实现方式,多数业务系系统还是使用数据库记录的字段来记录任务的执行状态,也就是记录中间的“软状态”,一个任务的状态流转一般可以通过数据库的行级锁来实现,这比使用Write-Ahead Log实现更简单、更快速。
分布式和集群
分布式:不同的多台服务器上面部署不同的服务模块(工程)
集群:不同的多台服务器上面部署相同的服务模块。通过分布式调度软件进行统一的调度,对外提供服务和访问。
Redis的数据类型
Redis五种数据类型:string、hash、list、set、zset
公用命令
del key
dump key:序列化给定key,返回被序列化的值
exists key:检查key是否存在
expire key second:为key设定过期时间,以秒计算,可以不写second,默认为秒
ttl key:返回key剩余时间,-1为永久,-2为失效
persist key:移除key的过期时间,key将持久保存
keys pattern:查询所有符号给定模式的key eg:keys *
randomkey:随机返回一个key
rename key newkey:修改key的名称
move key db:移动key至指定数据库中 eg:move a 1
type key:返回key所储存的值的类型
expirekey second的使用场景: 1、限时的优惠活动 2、网站数据缓存 3、手机验证码 4、限制网站访客频率
key的命名建议
key不要太长,尽量不要超过1024字节。不仅消耗内存,也会降低查找的效率
key不要太短,太短可读性会降低
在一个项目中,key最好使用统一的命名模式,如user:123:password
key区分大小写
String
string类型是二进制安全的,redis的string可以包含任何数据,如图像、序列化对象。一个键最多能存储512MB。
二进制安全是指,在传输数据的时候,能保证二进制数据的信息安全,也就是不会被篡改、破译;如果被攻击,能够及时检测出来
set key_name value:命令不区分大小写,但是key_name区分大小写
setnx key value:当key不存在时设置key的值。(SET if Not eXists),分布式锁的问题
setex:创建一个key,并且设置他的过期时间
get key_name
getrange key start end:获取key中字符串的子字符串,从start开始,end结束
setrange key offset value:设置从offset往后的值
mget key1 [key2 …]:获取多个key
getset key_name value:返回key的旧值,并设定key的值。当key不存在,返回nil
strlen key:返回key所存储的字符串的长度
incr key_name :INCR命令key中存储的值+1,如果不存在key,则key中的值话先被初始化为0再加1
INCRBY KEY_NAME 增量
DECR KEY_NAME:key中的值自减一
DECRBY KEY_NAME
append key_name value:字符串拼接,追加至末尾,如果不存在,为其赋值
String应用场景: 1、String通常用于保存单个字符串或JSON字符串数据 2、因为String是二进制安全的,所以可以把保密要求高的图片文件内容作为字符串来存储 3、计数器:常规Key-Value缓存应用,如微博数、粉丝数。INCR本身就具有原子性特性,所以不会有线程安全问题
hash
Redis hash是一个string类型的field和value的映射表,hash特别适用于存储对象。每个hash可以存储232-1(40亿左右)键值对。可以看成KEY和VALUE的MAP容器。相比于JSON,hash占用很少的内存空间。
常用命令
hset key_name field value:为指定的key设定field和value
hmset key field value[field1,value1]
hsetnx:当不存在才创建该field
hget key field
hmget key field[field1]
hgetall key:返回hash表中所有字段和值
hkeys key:获取hash表所有字段
hvals key:获取hash表所有值
hlen key:获取hash表中的字段数量
hdel key field [field1]:删除一个或多个hash表的字段
hexists:在key里面是否存在指定的field
hincrby key field increment:增加某个field的值
应用场景
Hash的应用场景,通常用来存储一个用户信息的对象数据。
相比于存储对象的string类型的json串,json串修改单个属性需要将整个值取出来。而hash不需要。
相比于多个key-value存储对象,hash节省了很多内存空间
如果hash的属性值被删除完,那么hash的key也会被redis删除
list
类似于Java中的LinkedList。
常用命令
lpush key value1 [value2]:从左侧插入,右边的先出,相当于一个栈
eg:lpush list 1 2 3 lrange list 0 -1 输出:3 2 1
rpush key value1 [value2]: 从右侧插入,左边的先出
eg:rpush list 1 2 3 lrange list 0 -1 输出:1 2 3
lpushx key value:从左侧插入值,如果list不存在,则不操作
rpushx key value:从右侧插入值,如果list不存在,则不操作
llen key:获取列表长度
lindex key index:获取指定索引的元素,从零开始
lrange key start stop:获取列表指定范围的元素
lpop key :从左侧移除第一个元素
prop key:移除列表最后一个元素
irem:删除指定个数的同一元素
eg:irem list 2 3 删掉了集合中的两个三
blpop key [key1] timeout:移除并获取列表第一个元素,如果列表没有元素会阻塞列表到等待超时或发现可弹出元素为止
brpop key [key1] timeout:移除并获取列表最后一个元素,如果列表没有元素会阻塞列表到等待超时或发现可弹出元素为止
ltrim key start stop :对列表进行修改,让列表只保留指定区间的元素,不在指定区间的元素就会被删除
eg:list1中元素1 2 3 4 5 ltrim list1 2 3 list1剩余元素:3 4
lset key index value :指定索引的值
linsert key before|after world value:在列表元素前或则后插入元素
应用场景
对数据大的集合数据删减
列表显示、关注列表、粉丝列表、留言评价...分页、热点新闻等
任务队列 list通常用来实现一个消息队列,而且可以确保先后顺序,不必像MySQL那样通过order by来排序
补充:
rpoplpush list1 list2 移除list1最后一个元素,并将该元素添加到list2并返回此元素 用此命令可以实现订单下单流程、用户系统登录注册短信等。
性能总结
它是一个字符串链表,left、right都可以插入添加; 如果键不存在,创建新的链表; 如果键已存在,新增内容; 如果值全移除,对应的键也就消失了。 链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了。
set
唯一、无序
sadd key value1[value2]:向集合添加成员
scard key:返回集合成员数
smembers key:返回集合中所有成员
sismember key member:判断memeber元素是否是集合key成员的成员
srandmember key [count]:返回集合中一个或多个随机数
srem key member1 [member2]:移除集合中一个或多个成员
spop key:移除并返回集合中的一个随机元素
smove source destination member:将member元素从source集合移动到destination集合
sdiff key1 [key2]:返回给定的第一个集合和其他集合的差集(即在key1中的值而在其他key中找不到)
sdiffstore destination key1[key2]:返回给定的第一个集合与其他的集合的差集并存储在destination中
eg:set1:1 2 3 set2:3 4 5 6 sdiffstore set3 set1 set2 smembers set3 result:1 2
sinter key1 [key2]:返回所有集合的交集
sunion key1 [key2]:返回所有集合的并集
对两个集合间的数据[计算]进行交集、并集、差集运算 1、以非常方便的实现如共同关注、共同喜好、二度好友等功能。对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存储到一个新的集合中。 2、利用唯一性,可以统计访问网站的所有独立 IP
zset
有序且不重复。每个元素都会关联一个double类型的分数,Redis通过分数进行从小到大的排序。分数可以重复
zadd key score1 memeber1
zcard key :获取集合中的元素数量
zcount key min max 计算在有序集合中指定区间分数的成员数
zcount key min max 计算在有序集合中指定区间分数的成员数
zrange key start stop 指定输出索引范围内的成员
zrangebyscore key min max 指定输出score区间内的成员
zrank key member:返回有序集合指定成员的索引
zrevrange key start stop :返回有序集中指定区间内的成员,通过索引,分数从高到底
zrem key member [member …] 移除有序集合中的一个或多个成员
zremrangebyrank key start stop 移除有序集合中给定的索引区间的所有成员(第一名是0)(低到高排序)
zremrangebyscore key min max 移除有序集合中给定的分数区间的所有成员
常用于排行榜:
如推特可以以发表时间作为score来存储
存储成绩
还可以用zset来做带权重的队列,让重要的任务先执行
解析配置文件
#是否在后台运行;no:不是后台运行
daemonize yes
#是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
protected-mode yes
#redis的进程文件
pidfile /var/run/redis/redis-server.pid
#redis监听的端口号。
port 6379
#此参数确定了TCP连接中已完成队列(完成三次握手之后)的长度, 当然此值必须不大于Linux系统定义的/proc/sys/net/core/somaxconn值,默认是511,而Linux的默认参数值是128。当系统并发量大并且客户端速度缓慢的时候,可以将这二个参数一起参考设定。该内核参数默认值一般是128,对于负载很大的服务程序来说大大的不够。一般会将它修改为2048或者更大。在/etc/sysctl.conf中添加:net.core.somaxconn = 2048,然后在终端中执行sysctl -p。
tcp-backlog 511
#指定 redis 只接收来自于该 IP 地址的请求,如果不进行设置,那么将处理所有请求
#bind 127.0.0.1
#bind 0.0.0.0
#配置unix socket来让redis支持监听本地连接。
# unixsocket /var/run/redis/redis.sock
#配置unix socket使用文件的权限
# unixsocketperm 700
# 此参数为设置客户端空闲超过timeout,服务端会断开连接,为0则服务端不会主动断开连接,不能小于0。
timeout 0
#tcp keepalive参数。如果设置不为0,就使用配置tcp的SO_KEEPALIVE值,使用keepalive有两个好处:检测挂掉的对端。降低中间设备出问题而导致网络看似连接却已经与对端端口的问题。在Linux内核中,设置了keepalive,redis会定时给对端发送ack。检测到对端关闭需要两倍的设置值。
tcp-keepalive 0
#指定了服务端日志的级别。级别包括:debug(很多信息,方便开发、测试),verbose(许多有用的信息,但是没有debug级别信息多),notice(适当的日志级别,适合生产环境),warn(只有非常重要的信息)
loglevel notice
#指定了记录日志的文件。空字符串的话,日志会打印到标准输出设备。后台运行的redis标准输出是/dev/null。
logfile /var/log/redis/redis-server.log
#是否打开记录syslog功能
# syslog-enabled no
#syslog的标识符。
# syslog-ident redis
#日志的来源、设备
# syslog-facility local0
#数据库的数量,默认使用的数据库是DB 0。可以通过SELECT命令选择一个db
databases 16
# redis是基于内存的数据库,可以通过设置该值定期写入磁盘。
# 注释掉“save”这一行配置项就可以让保存数据库功能失效
# 900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)
# 300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)
# 60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)
save 900 1
save 300 10
save 60 10000
#当RDB持久化出现错误后,是否依然进行继续进行工作,yes:不能进行工作,no:可以继续进行工作,可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误
stop-writes-on-bgsave-error yes
#使用压缩rdb文件,rdb文件压缩使用LZF压缩算法,yes:压缩,但是需要一些cpu的消耗。no:不压缩,需要更多的磁盘空间
rdbcompression yes
#是否校验rdb文件。从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和。这跟有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗,所以如果你追求高性能,可以关闭该配置。
rdbchecksum yes
#rdb文件的名称
dbfilename dump.rdb
#数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
dir /data
############### 主从复制 ###############
#复制选项,slave复制对应的master。
# slaveof <masterip> <masterport>
#如果master设置了requirepass,那么slave要连上master,需要有master的密码才行。masterauth就是用来配置master的密码,这样可以在连上master后进行认证。
# masterauth <master-password>
#当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:1) 如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。2) 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
slave-serve-stale-data yes
#作为从服务器,默认情况下是只读的(yes),可以修改成NO,用于写(不建议)。
slave-read-only yes
#是否使用socket方式复制数据。目前redis复制提供两种方式,disk和socket。如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave。socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave。disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件。socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用socket方式。
repl-diskless-sync no
#diskless复制的延迟时间,防止设置为0。一旦复制开始,节点不会再接收新slave的复制请求直到下一个rdb传输。所以最好等待一段时间,等更多的slave连上来。
repl-diskless-sync-delay 5
#slave根据指定的时间间隔向服务器发送ping请求。时间间隔可以通过 repl_ping_slave_period 来设置,默认10秒。
# repl-ping-slave-period 10
#复制连接超时时间。master和slave都有超时时间的设置。master检测到slave上次发送的时间超过repl-timeout,即认为slave离线,清除该slave信息。slave检测到上次和master交互的时间超过repl-timeout,则认为master离线。需要注意的是repl-timeout需要设置一个比repl-ping-slave-period更大的值,不然会经常检测到超时。
# repl-timeout 60
#是否禁止复制tcp链接的tcp nodelay参数,可传递yes或者no。默认是no,即使用tcp nodelay。如果master设置了yes来禁止tcp nodelay设置,在把数据复制给slave的时候,会减少包的数量和更小的网络带宽。但是这也可能带来数据的延迟。默认我们推荐更小的延迟,但是在数据量传输很大的场景下,建议选择yes。
repl-disable-tcp-nodelay no
#复制缓冲区大小,这是一个环形复制缓冲区,用来保存最新复制的命令。这样在slave离线的时候,不需要完全复制master的数据,如果可以执行部分同步,只需要把缓冲区的部分数据复制给slave,就能恢复正常复制状态。缓冲区的大小越大,slave离线的时间可以更长,复制缓冲区只有在有slave连接的时候才分配内存。没有slave的一段时间,内存会被释放出来,默认1m。
# repl-backlog-size 5mb
#master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度。单位为秒。
# repl-backlog-ttl 3600
#当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举。
slave-priority 100
#redis提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于N,mater就禁止写入。master最少得有多少个健康的slave存活才能执行写命令。这个配置虽然不能保证N个slave都一定能接收到master的写操作,但是能避免没有足够健康的slave的时候,master不能写入来避免数据丢失。设置为0是关闭该功能。
# min-slaves-to-write 3
#延迟小于min-slaves-max-lag秒的slave才认为是健康的slave。
# min-slaves-max-lag 10
# 设置1或另一个设置为0禁用这个特性。
# Setting one or the other to 0 disables the feature.
# By default min-slaves-to-write is set to 0 (feature disabled) and
# min-slaves-max-lag is set to 10.
############### 安全相关 ###############
#requirepass配置可以让用户使用AUTH命令来认证密码,才能使用其他命令。这让redis可以使用在不受信任的网络中。为了保持向后的兼容性,可以注释该命令,因为大部分用户也不需要认证。使用requirepass的时候需要注意,因为redis太快了,每秒可以认证15w次密码,简单的密码很容易被攻破,所以最好使用一个更复杂的密码。注意只有密码没有用户名。
# requirepass foobared
#把危险的命令给修改成其他名称。比如CONFIG命令可以重命名为一个很难被猜到的命令,这样用户不能使用,而内部工具还能接着使用。
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#设置成一个空的值,可以禁止一个命令
# rename-command CONFIG ""
############### 进程限制相关 ###############
# 设置能连上redis的最大客户端连接数量。默认是10000个客户端连接。由于redis不区分连接是客户端连接还是内部打开文件或者和slave连接等,所以maxclients最小建议设置到32。如果超过了maxclients,redis会给新的连接发送’max number of clients reached’,并关闭连接。
# maxclients 10000
#redis配置的最大内存容量。当内存满了,需要配合maxmemory-policy策略进行处理。注意slave的输出缓冲区是不计算在maxmemory内的。所以为了防止主机内存使用完,建议设置的maxmemory需要更小一些。
# maxmemory <bytes>
#内存容量超过maxmemory后的处理策略。
#volatile-lru:利用LRU算法移除设置过过期时间的key。
#volatile-random:随机移除设置过过期时间的key。
#volatile-ttl:移除即将过期的key,根据最近过期时间来删除(辅以TTL)
#allkeys-lru:利用LRU算法移除任何key。
#allkeys-random:随机移除任何key。
#noeviction:不移除任何key,只是返回一个写错误。