redis概念
redis是一个开源的、使用C语言编写的基于内存可持久化的key-value非关系型数据库。
redis优点
(1)性能高
redis读的速度是110000次/s,写的速度81000次/s。
(2)丰富的数据类型
redis支持的数据类型有String、List、Set、Hash、sorted set
(3)原子性
redis操作具有原子性,要么成功执行,要么失败完全不执行
(4)丰富的特性
支持发布/订阅、数据持久化、key过期等特性
redis缺点
(1)持久化
redis持久化方案有RDB和AOF。前者redis通过定时快照的方式将数据写入到硬盘上,对于非正常redis关闭的情况下,可能会导致数据丢失,而且这种持久化操作每次都会把所有数据写入硬盘,代价非常高。后者redis只追踪变化的数据,但是追加的log会越来越大,并且所有操作均重新执行一遍,恢复速度慢。
(2)耗内存
redis是基于内存操作的,对内存的要求较高。
redis下载
官方网站:http://redis.io/download 可以根据需求下载不同版本
#redis是C语言开发的,所以需要gcc环境 |
redis.conf配置
配置 | 默认 | 说明 |
---|---|---|
daemonize | no | 是否后台运行 |
port | 6379 | 端口 |
bind | 127.0.0.1 | 绑定ip,默认只允许本机访问redis-server |
timeout | 0 | 客户端连接超时时间,单位为秒,默认0表示关闭此设置 |
loglevel | notice | redis支持debug、verbose、notice、warning |
tcp-keepalive | 300 | TCP连接保活策略,默认单位为秒,如果设置60秒,则server端会每60秒向连接空闲的客户端发送一次ACK请求,以检查客户端是否存活,对于无响应的客户端则会关闭其连接 |
logfile | redis日志文件,默认为空,如果设置了daemonize yes,redis会把日志输出到/dev/null中 | |
databases | 16 | redis数据库总数量,数据库索引是0-15 |
save |
save 900 1 save 300 10 save 60 10000 |
RDB持久化策略,默认是当60秒内有10000个key更改,触发一次RDB快照;当300秒内有10个key更改,触发一次RDB快照;当900秒内有1个key更改,触发一次RDB快照 |
stop-writes-on-bgsave-error | yes | 如果用户开启了RDB持久化,那么当redis持久化到硬盘出现失败,redis会停止接受所有的写请求,当下一次持久化成功后,redis会恢复接受写请求 |
rdbcompression | yes | 对于存储在硬盘的快照,redis支持压缩存储,如果不想消耗cpu,可以关闭此配置,但是存储在硬盘的数据会越来越大 |
rdbchecksum | yes | 在存储快照后,redis支持对数据校验,但是会消耗大约10%的性能,如果希望性能最大化,可以关闭此功能 |
dbfilename | dump.rdb | 设置快照文件的名称 |
dir | ./ | 配置快照存放路径 |
replicaof |
redis提供主从功能,通过slaveof配置一台服务器作为另一台从服务器 | |
masterauth |
如果主服务器设置了requirepass,则从redis配置中要使用masterauth来校验密码 | |
slave-serve-stale-data | yes | 当从redis失去与主redis连接,或者主从正在同步时,redis是否处理客户端发来的请求 |
replica-read-only | yes | 控制从redis是否接受写请求 |
rep-timeout | 60 | 主从同步情况可能会发生超时,用户可以设置超时时限,不过一定要确保比repl-ping-replica-period的值要大 |
repl-disable-tcp-nodelay | no | 控制主从同步是否禁用TCP_NODELAY。如果开启TCP_NODELAY,那么主redis会使用更少的TCP包和更少的带宽来向从redis传输数据,但是会增加一些同步的延迟,大概40ms左右。如果关闭了TCP_NODELAY,那么数据同步延迟会降低,但是会消耗更多的带宽 |
repl-backlog-size | 1mb | 设置队列长度,队列长度是redis中的一个缓冲区,如果与从redis断开连接后,主redis会用这个缓冲区缓存发送的数据 |
repl-backlog-ttl | 3600 | 如果主redis等了一段时间后,还是无法与从redis连接,那么缓冲区数据将被清除;如果设置为0表示永不清除 |
min-replicas-to-write | 3 | 与min-replicas-max-lag配合使用 |
min-replicas-max-lag | 10 | 表示当主redis发现超过M个连接延迟大于N秒时,那么主redis就停止接受写请求。从redis每秒都会向主redis发出ping,而主redis会记录每一个从redis发来的ping时间点,所以主redis能够了解从redis的运行情况 |
replica-priority | 100 | 规定从redis优先级,在主redis持续不正常工作时,优先级高的将成为主redis,而编号越小表示优先级越高,当编号被设置为0时表示这个从redis永远不会被选中,默认是100 |
requirepass | foobared | 设置密码验证,当客户端连接redis-server时,需要进行密码验证 |
rename-command CONFIG “” | 对redis指令进行更名,避免外部调用。这里对CONFIG重命名 | |
max-clients | 10000 | 设置redis-server允许客户端的最大连接数 |
maxmemory |
设置redis可以使用的内存量,当超过此内存上限,redis将根据maxmemory-policy规则移除内部数据 | |
maxmemory-policy | noeviction | 指定redis数据淘汰策略,redis提供了volatile-lru、allkeys-lru、volatile-random、allkeys-random、volatile-ttl、noeviction六种数据淘汰策略 |
axmemory-samples | 5 | LRU和最小TTL算法都并非是精确算法,而是估算值,可以设置样本大小,redis默认检查5个key并选择其中LRU那个 |
appendonly | no | redis支持数据持久化,目前redis持久化方案有RDB、AOF |
appendfilename | “appendonly.aof” | 设置aof文件名称 |
appendfsync | everysec | 一次fsync()调用,操作系统会将缓存指令写入硬盘。redis支持三种模式,no:不调用,让操作系统自行决定sync的时间,redis性能更快;always:每次写请求后都会调用,这种情况redis会相对较慢,但数据最安全;everysec:每秒钟调用一次 |
no-appendfsync-on-rewrite | no | bgrewriteaof机制,在一个子进程执行aof重写,不会阻塞主进程处理其余指令。但是当bgrewriteaof和主进程写aof时,两种均操作硬盘,bgrewriteaof会涉及大量硬盘操作,这样导致了主进程aof写入的阻塞,当no-appendfsync-on-rewrite设置为yes时表示这就相当于将appendfsync设置为no,不会有磁盘操作,只是写入缓冲区,不会出现阻塞,但是如果这个时候redis挂掉,会丢失数据。如果此参数设置为no,是最安全的方式,但是要忍受阻塞的情形 |
auto-aof-rewrite-percentage | 100 | redis记录前一次aof文件大小作为基准值,当当前aof文件超过这个基准100%(默认100)时,触发bgrewriteaof,也就是用一个子进程重写aof。该配置为0时表示禁用重写 |
auto-aof-rewrite-min-size | 64mb | 当aof文件大于64mb时,触发bgrewriteaof |
lua-time-limit | 5000 | lua脚本最大运行时间,默认单位ms |
redis数据淘汰策略
*volatile-lru:使用LRU算法移除过期集合中的key
*allkeys-lru:使用LRU算法移除key
*volatile-random:在过期集合中随机移除key
*allkeys-random:随机移除key
volatile-ttl:移除那些ttl值最小的key,即移除最近要过期的key
noeviction:不进行移除
redis持久化
redis支持RDB和AOF两种持久化机制,redis持久化就是将内存中的数据写入到硬盘中,避免redis挂掉导致数据丢失。
RDB持久化
RDB持久化是把当前数据生成快照存储到硬盘中。触发方式有手动触发(save【阻塞式】、bgsave【推荐】)和自动触发(redis.conf中配置save)
RDB文件存储路径,通过redis.conf中的dir配置
(1)优点
*RDB文件是压缩的二进制文件,代表redis在某个时间点的快照,空间占用小
*redis加载RDB从硬盘中恢复数据远远快于AOF方式
(2)缺点
RDB没有做到实时数据持久化,如果数据更改没有达到RDB持久化触发的条件,redis在这个时候突然挂掉,那么就会导致数据丢失
AOF持久化
AOF持久化是以独立日志的方式记录每次的写命令,重启时再次执行AOF文件中的命令达到数据恢复。AOF主要是解决数据持久化的实时性问题
(1)AOF开启
通过redis.conf中的appendonly yes开启,通过appendfilename配置名称,通过dir配置数据存储路径
(2)AOF流程
*redis-server启动,如果AOF机制开启,那么初始化AOF状态,并且如果存在AOF文件,读取AOF文件
*随着redis不断接受命令,每个写命令都会被添加到AOF文件,AOF文件大小会增加,redis会记录之前aof大小,当目前aof文件大小达到auto-aof-rewrite-percentage、auto-aof-rewrite-min-size设定的值后,就会触发rewrite
*fork出一个子进程进行rewrite,重写新的aof文件,而父进程继续接受命令,现在的写命令都会添加aof_rewrite_buf_blocks缓冲区
*当子进程rewrite结束后,父进程收到子进程退出信号,把缓冲区的数据添加到rewrite后新的aof文件中,随后rename新的aof文件,覆盖旧的aof文件
*至此一个rewrite走完,继续第2步
(3)优点
*解决了数据持久化实时性的问题
*你可以设置不同的fsync策略,比如无fsync,每秒钟一次fsync,或者每次执行写入命令时fsync。AOF的默认策略为每秒钟fsync一次,在这种配置下,redis仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据(fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)
(4)缺点
相对于RDB文件,AOF文件的大小通常大于RDB文件,根据fsync策略,AOF速度要慢于RDB
redis-cluster集群
redis cluster集群是一个由主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis cluster集群不需要sentine哨兵也能完成节点移除和故障转移功能。需要将每个节点设置成集群模式,这种集群没有中心节点,可水平扩展。
(1)无中心化就是客户端直接与节点相连,不需要proxy代理层,客户端只需要连接到集群的任意节点就行
(2)集群中所有的redis节点彼此互联
(3)cluster集群中内置16384(编号0-16383)个哈希槽,redis根据节点数量均匀的将槽位分到不同节点。当客户端set一个key时,redis对key使用crc16算法算出一个结果,然后把结果对16384取模,这个key都会对应到0-16383之间的槽位。
(4)水平扩容-当集群中新增了一个节点,redis会从其他各个节点取出部分槽位分到新加入的节点
(5)集群进入fail状态的必要条件
*某个主节点和其所有从节点全部挂掉,集群进入fail状态
*如果集群超过半数以上master挂掉,无论是否存在slave,集群进入fail状态
*如果集群任意master挂掉,且master没有slave,集群进入fail状态
(6)redis投票机制-投票是所有master节点参与的,如果半数以上master节点无法与某个master节点通信,则认为此master节点挂掉