Redis(配置)

阅读数:153 评论数:0

跳转到新版页面

分类

架构学

正文

Redis是一个开源的,使用C语言编写的、支持网络交互的、可基于内存也可持久化的key-value数据库。

一、Redis的持久化

Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。

RDB,简单说就是在不同的时间点,将Redis存储的数据生成快照并存储到磁盘等介质上。

AOF,则是换了一个角度来实现持久化,那就是将Redis执行过的所有写指令记录下来,在下次Redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复。

如果RDB和AOF同时使用,Redis重启的话,则会优先采用AOF方式来进行恢复,这是因为AOF方式的数据恢复完整度更高。

1、RDB

Redis在进行数据持久化过程中,会先将数据写到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次久化好的文件。正是这种特性,让我们可以随时进行备份,因为快照文件总是完整可用的。

对于RDB方式,Redis会单独创建一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了Redis极高的性能。

如果对于数据恢复的完整性不是非常敏感,RDB方式要比AOF更加高效,如果对数据的完整性非常敏感,当Redis故障时,仍然会有近5分钟的数据丢失。

2、AOF

默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,Redis仍然可以保持很好的处理性能、即使Redis故障,也只会丢失最近1秒的数据。

如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导制日志写入不完整,也没有关系,Redis提供了redis-check-aof工具,可以用来进行日志修复。

Redis提供了AOF文件重写机制,即当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。

在进行AOF重写时,仍然采用先写临时文件,全部完成后再替换的流程。如果直接执行bgrwriteaof命令,那么Redis会生成一个全新的AOF文件。

在重写即将开始之际,Redis会创建一个“重写子进程”,这个子进程会首先读取现有AOF文件,并将其包含的指令进行分析压缩并写到一个临时文件中。与此同时,主工作进程会将新接收到写指令一边累积到内存缓存区中,一边继续写入原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。当“重写子进程“完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。当追加结束后,Redis就会用新的AOF文件来代替旧的AOF文件,之后再有新的写指令,就都会追加新的AOF文件中了。

二、主从

Redis支持主从同步,而且也支持一主多从以及多级结构。在主从架构中,从服务器通常被设置为只读模式,这样可以避免从服务器的数据被误修改。但是从服务器仍然可以接受CONFIG等指令,如果必须将从服务器直接暴露到不安全的网络环境中,可以考虑给重要指令进行重命名,来避免被外人执行。

在主从架构中,可以考虑关闭服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能。

Redis的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低Redis的处理性能。从服务顺向主服务器发出SYNC指令,当主服务器接受到此命令后,就会调用BGSAVE指令来创建一个子进程专门进行数据持久化工作,也就是将主服务器的数据写入RDB文件中。在BGSAVE指令执行完成后,主服务器会将持久化好的RDB文件发送给从服务器,从服务器接到此文件后会将其存储到磁盘上,然后再读取到内存中。这个动作完成后,主服务器会将这段时间缓存的写指令再以Redis协议的格式发送给从服务器。

三、事务

MULTI 用来组装一个事务
EXEC 用来执行一个事务
DISCARD 用来取消一个事务
WATCH 用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行。支持同时监视多个key。

四、配置

1、通用配置

daemonize 默认情况下,Redis并不是以daemon形式来运行的。当以daemon形式运行时,Redis会生成一个pid文件,默认会生成在/var/run/redis.pid,也可以通过pidfile来指定文件生成的位置。
bind 默认情况下,Redis会响应本机所有可用网卡的连接请求,可以通过bind配置项来指定要绑定的IP。
port 默认服务端口是6379,可以通过port配置项来修改,如果端口设置为0的话,Redis便不会监听端口了。
unixsocket 还支持unix socket方式来接收请求,可以通过unixsocket配置项来指定unix socket文件路径,并通过unixsocketperm来指定文件的权限。
timeout

当一个redis-client一直没有请求发向server端,那以server端有权主动关闭这个连接,可以通过timeout来设置空闲超时时限,0表示永不关闭。

tcp-keepalive

TCP连接策略,可以通过tcp-keepalive配置项来进行设置,单位为秒,如果设置为0,则不会进行保活检测。

loglevel

通过loglevel配置项设置日志等级,共分四级,即debug verbose notice warning

logfile

通过logfile配置项来设置文件的生成位置。如果设置为空,则Redis会将日志输出到标准输出。在daemon情况下,日志会被写到/dev/null中。

syslog-enabled

如果希望日志打印到syslog中,通过syslog-enabled来控制。另外,syslog-ident还可以让你指定syslog里的日志标志。

databases

通过databases可以设置数据库的总数量。数据库编号从0开始。

2、快照

stop-writes-on-bgsave-error

如果用户开启了RDB,那么Redis持久化失败时,Redis会停止接受所有的写请求,也可以使用stop-writes-on-bgsave-error来关闭这个功能。

rdbcompression

对于存储到磁盘的快照,可以设置是否进行压缩存储,如果是的话,Redis会采用LZF算法进行压缩。可以使用rdbcompression配置项来关闭这个功能。

rdbchecksum

在存储快照后,可以使用CRC64算法来进行数据检验,但是这样会增加性能消耗,可以使用rdbchecksum 配置项来关闭此功能。

dbfilename 可以通过dbfilename来设置快照文件的名称
dir

可以通过dir来设置快照文件存放在路径。

3、复制

requirepass

如果主Redis设置了验证密码的话(使用requirepass来设置),则在从Redis的配置中要使用masterauth来设置检验密码。

slave-read-only

通过slave-read-only来设置从Redis是否只读。

rename-command

只读的从Redis并不适合直接暴露给不可信的客户端,可以使用rename-command指令来将一些可能有破坏办的命令重命名。

repl-ping-slave-period

从Redis会周期性的向主Redis发PING包,可以通过repl-ping-slave-period指令控制其周期。

repl-disable-tcp-nodelay

可以通过repl-disable-tcp-nodelay来设置 主从同步时是否禁用TCP_NODELAY,如果开启了TCP_NODEPLAY,那么主Redis会使用更少的TCP包和更少的带宽来向从Redis传输数据。但是这可能会增加一些同步的延迟,大概会达到40毫秒。

repl-backlog-size

通过repl-backlog-size设置同步队列长度,队列长度(backlog)是主Redis的一个缓冲区,在与从Redis断开连接期间,主Redis会用这个缓冲区来缓存应该发给从Redis的数据。这样的话,当从Redis重新连接上之后,就不必重新全量同步数据。

repl-backlog-ttl

如果主Redis等待了一段时间之后,还是无法连接上从Redis,那么缓冲队列中的数据将被清理掉,这个时间可以通过repl-backlog-ttl设置,如果设置为0,则表示永不清理。

slave-priority

在众多的从Redis中可以设置优先级,在主Redis不正常的情况下,优先级高的从Redis将会升级为主Redis,slave-priority,如果设置为0,这个从Redis永远也不会被选中。

min-slaves-to-write

假如主Redis发现有超过M个从Redis的连接延时超过N秒,那么主Redis就停止接受外来的写请求。如果min-slaves-to-write 3, min-slaves-max-lag 10,那么有3个从Redis的连接延迟超过10秒,那么主Redis就不再接爱外部的写请求。上述两个配置中有一个被置为0,则这特性将被关闭。

4、安全

equirepass 可以设置密码验证
rename-command

如果把命令改为空安符串,就是禁用掉CONFIG命令。

5、限制

maxclients 设置Redis同时可以与多少个客户端进行连接,当你无法设置进程文件句柄限制时,Redis会设置为当前的文件句柄限制值减去32,因为Redis会为自身处理逻辑留一些句柄。
maxmemoery <bytes> 设置Redis可以使用的内存理,一旦到达内存使用上限,Redis会尝试移除内部数据,移除规则可以通过maxmemory-policy来指定。
maxmemory-policy 可以是volatile-lru(LRU算法移除过期集合中的key)、allkey-lru(使用LRU算法移除key)、volatile-random(在过期集合中移除随机的key)、allkeys-random(移除随机的key)、volatile-ttl(移除那此TTL值最小的key)、noeviction(不进行移除,只是返回错误信息)

6、aof

appendfilename 设置aof文件的名称 。
appendfsync aof缓存的模式(no=让操作系统自行决定,always=每次写请求,everysec=每秒)
no-appendsync-on-rewrite 如果后台持久化需要一个很大的IO操作,那么Redis可能会在fsync调用时卡住,使用这引配置项
auto-aof-rewrite-percentage和auto-aof-rewrite-min-size 用于Redis自动启动重写。

7、lua脚本

lua-time-limit(ms) ,设置lua脚本的最大运行时间,如果设置为0或负数,则不会有时间限制。

8、慢日志

slowlog-log-slower-than

slow-max-len

慢日志是用于Redis记录那些超过指定查询时间的日志,执行的时间不包括和客户羰的IO操作和响应时间等,而只是Redis执行命令的时间。针对慢日志,可以设置两个参数,一个是执行时长,另一个是长度。

9、支持主配置中引入外部配置文件

include /path/to/other.conf

五、Redis数据类型

1、String

这是简单的key-value类型,value其实不仅是String,也可以是数字。

应用场景:可以完全实现目前Memcached的功能,并且效率更高。

2、Hash

Redis Hash对应的Value内部实现就是一个HashMap,实际这里会有两种不同实现,这个Hash的成员比少时Redis为节省内存会采用类似一维数组的方式秋紧凑存储,而不会采用真正的HashMap结构,对应的redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。

3、List

Redis的list的实现为一个双向链表,即可以支持查找和遍历,更方便操作,不过带了部分额外的内存开销。

4、Set

实现方式:set的内部实现是一个value永远为null的HashMap,实际就是通过计算hash方式来快速排重。

5、Sort Set

内部使用HashMap和跳表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳表里存放的是所有成员,使用跳表的结构可以获得比较高的查找效率,并且在实现上比较简单。

六、API的原子性

Redis的操作之所以是原子性的,是因为Redis是单线程的。对Redis来说,执行get、set等API,都是一个一个的任务,这些任务都会由Redis的线程去负责执行,任务要么执行失败,要么成功。Redis本身提供的所有API都是原子操作,Redis中的事务其实是要保证批量操作的原子性。

七、集群搭建(Redis5)

1、安装gcc

2、安装redis5(make & make install)

3、修改redis配置文件

protected-mode no       # 关闭保护模式  打开(yes)时下边bind配置才生效
 
     daemonize yes             # 守护进程模式开启(后台启动)
 
     #bind 127.0.0.1             #默认只监听本机访问也可以将需要访问的IP空格分隔添加在后面,需要注释掉
 
     cluster-enabled yes      #启用集群
 
     cluster-config-file nodes-6379.conf      #集群节点配置文件

4、新建集群节点文件夹

此前准备了两台机器:10.1.101.88、10.1.101.89 本文集群试用三主三从六个节点,所以分别在两台机器上创建三个文件夹为:

/u01/redis/cluster/6379

/u01/redis/cluster/6380

/u01/redis/cluster/6381

5、拷贝配置文件

分别将redis.conf拷贝到以上两个文件夹并修改端口号。

6、启动redis

redis-server   /u01/redis/cluster/6379/redis_6379.conf
 
     redis-server   /u01/redis/cluster/6380/redis_6380.conf
 
     redis-server   /u01/redis/cluster/6381/redis_6381.conf

7、启动集群

redis-cli --cluster create 10.1.101.88:6379  10.1.101.89:6379 10.1.101.88:6380 10.1.101.89:6380 10.1.101.88:6381 10.1.101.89:6381 --cluster-replicas 1

8、常见问题

(1)No route to host

是防火墙的问题。

(2)waiting for the cluster to join

redis集群不仅需要开通redis客户端的端口,还需要开通集群总线端口,集群总线端口为redis客户端连接的端口+10000

(3)node is not empty

将此节点下的aof rdb nodes.conf删除之后再执行集群创建。

9、检查集群

redis-cli --cluster check 10.1.101.88:6379

 




相关推荐

原子性是数据库的事务中的特性,指一个事务中的所有操作,要么全部完成,要么全部不完成。对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。 Red