- NoSQL
- Redis基础
- Redis配置文件基础
- Redis的持久化
- Redis的复制
- Redis的集群
一、NoSQL
(一)基本概念
- NoSQL:Not Only SQL,非关系型、分布式、开源、水平可扩展的数据库
- 特性:数据量大、数据变化非常快(数据增长快、流量分布变化大、数据间耦合结构变化快)、数据源很多
(二)设计原则
(1)CAP理论:
- 一个分布式系统不可能同时满足C、A、P三个特性,最多可同时满足其中两者;对于分布式系统满足分区容错性几乎是必须的
- C:Consistency,多个数据节点上的数据一致
- A:Availablity,用户发出请求后的有限时间范围内返回结果
- P:Partition tolerence,网络发生分区后(network partition),服务是否依然可用
(2)BASE:BA,S,E,基于CAP演化而来
- BA:Basically Available,基本可用
- S:Soft state,软状态/柔性事务,即状态可以在一个时间窗口内是不同步的
- E:Eventually consistency,最终一致性
(三)分类和主流产品
- Key Value / Tuple Store:键值存储,DynamoDB, redis
- Wide Column Store / Column Families:列式数据库,hbase
- Document Store:文档数据库,mongodb, Elastic
- Graph Databases:图式数据库,Neo4j
- Time Series / Streaming Databases:时间序列存储
二、Redis基础
(一)简介:
- 开源、内存存储、数据结构存储
- 可用作:数据库、缓存、消息队列
- 数据结构:字符串、列表(数组)、hashes(关联数组)、集合、有序集合、bitmaps、hyperloglogs、空间索引
(二)程序环境:
- 配置文件:/etc/redis.conf
- 主程序:/usr/bin/redis-server
- 端口:6379/tcp
- 客户端:/usr/bin/redis-cli
- Unit File:/usr/lib/systemd/system/redis.service
- 数据目录:/var/lib/redis
(三)客户端的基本操作
(1)K/V 数据结构
- key:直接ASCII字符串;
- value:strings, lists, hashes, sets, sorted sets, bitmaps, hyperloglogs
(2)radis-cli工具的使用
交互式界面:直接输入radis-cli进入
帮助:输入HELP,按Tab键切换value类型
数据库:只有0-15共16个数据库,使用
SELECT #
命令切换,默认为0数据库
- @string
SET:新增一条键值对
GET:查看键对应的值
EXISTS
INCR:整数值自增1
DECR:整数值自减1
SETNX:只在没有此键时添加键值对
SETEX:添加一条键值对并设定过期时间
INCRBYFLOAT:按给定数值增加整数值
MGET:查看多个键对应的值
MSET:新增多条键值对
SET:新增,GET:查询,APPEND:添加,STRLEN:长度
SETNX:不存在时新增,INCR:自增1,INCRBY count 2:自增2,DEL:删除
- @list:数组
LPUSH:从左侧新增键值对
RPUSH:从右侧新增键值对
LPOP:从左侧移除键值对
RPOP:从右侧移除键值对
LPUSHX:仅当list存在时,从左侧新增键值对
RPUSHX:仅当list存在时,从右侧新增键值对
LRANGE:查看某个范围
LINDEX:通过索引查看
LSET:通过list的索引修改元素的值
LPUSH:从左侧添加,LINDEX weekdays 0:查看索引为0的元素值
LRANGE weekdays 0 4:查看索引0至4的元素值
LINSERT weekdays AFTER Tue Wed:在元素后Tue插入Wed
LPOP:左侧移除,RPOP:右侧移除,LLEN:list的长度
- @set:集合
SADD:集合中添加成员
SPOP:从集合中随机删除成员
SREM :从集合中删除成员
SRANDMEMBER:随机查看集合中的成员
SINTER:做交集
SUNION:做并集
SADD:添加成员,SMEMBERS:查看成员
SINTER:查看交集结果,SUNION:查看并集结果
SREM:删除指定成员,SPOP:随机删除成员
- @sorted_set:有序集合
ZADD:从集合中添加成员,若存在则为更新成员的值
ZCARD:查看有序集合成员数
ZCOUNT:按照所赋予的值,输出指定排序范围的成员数
ZRANK:按照所赋予的值,输出指定排序范围的成员
ZADD:添加有序集合的成员,ZSCORE:查看成员所赋予的值
ZRANK:查看指定成员的排序,ZRANGE:查看指定排序范围的成员,ZRANGEBYSCORE:查看指定排序范围的成员
- @hash:关联数组
HSET:新增包含一个键值对的关联数组
HMSET:新增包含多个键值对的关联数组
HGET:查看关联数组的一个键值对
HMGET:查看关联数组的多个键值对
HKEYS:查看关联数组的所有键
HVALS:查看关联数组的所有值
HDEL:删除关联数组的键值对
HGETALL:查看关联数组的所有键和对应的值
HMSET:在一个hash中创建多个键值对,HKEYS:查看键,HVALS:查看键对应的值
HGETALL:查看hash的所有键值对,HDEL:删除键值对
- @pubsub
PUBLISH:向频道扇出一条信息
SUBSCRIBE:订阅指定频道
UNSUBSCRIBE:退订指定频道
PSUBSCRIBE:按pattern规则订阅频道
PUNSUBSCRIBE:按pattern规则退订频道
PUBLISH:扇出信息
SUBSCRIBE:订阅并接受信息
@geo:空间索引
@server
Server相关的命令:
CLIENT GETNAME:查询当前连接名称
CLIENT KILL:杀死客户端的连接
CLIENT KILL [ip:port] [ID client-id] [TYPE normal|master|slave|pubsub] [ADDR ip:port] [SKIPME yes/no]
CLIENT LIST:列出客户端连接
CLIENT PAUSE:暂停执行客户端指令一段时间
CLIENT PAUSE timeout
CLIENT REPLY:告诉服务器是否回应指令
CLIENT SETNAME:设置当前连接名称
SHUTDOWN [NOSAVE|SAVE]:关闭服务器
CONFIG GET:查看配置参数
CONFIG RESETSTAT:重置配置参数
CONFIG REWRITE:将配置写入配置文件,实现运行时永久修改
CONFIG SET:设置配置参
数
INFO:INFO [section],服务器状态信息查看,可分为多个secion查看
FLUSHDB:清空当前数据库
FLUSHALL:清空所有数据库
CONFIG SET:实时修改配置
CONFIG REWRITE:配置文件中自动生成相应配置信息
INFO:服务器状态信息
三、Redis配置文件基础
配置文件分为如下章节:
INCLUDES:包含其他配置文件的路径
NETWORK:网络配置项
GENERAL:基本配置项
SNAPSHOTTING:快照持久化相关配置
REPLICATION:复制相关配置
SECURITY:安全相关配置
LIMITS:限制相关的配置
SLOW LOG:慢日志相关的配置
ADVANCED CONFIG:高级配置通用配置项:
daemonize on
supervised no
loglevel notice:日志级别
pidfile /var/run/redis/redis.pid:pid文件路径
logfile /var/log/redis/redis.log:日志文件路径
databases:设定数据库数量,默认为16个,每个数据库的名字均为整数,从0开始编号,默认操作的数据库为0网络配置项:
bind IP:绑定IP
port PORT:监听端口
protected-mode yes:安全模式
tcp-backlog 511:后援队列长度
unixsocket:socket文件路径
timeout:连接的空闲超时时长安全配置:
requirepass <PASSWORD>
rename-command <COMMAND> <NEW_CMND_NAME>:修改命令名称
在AOF或Replication环境中,不推荐使用
设置密码后,在redis-cli中使用AUTH password命令验证密码
-
Limits相关的配置:
maxclients 10000:并发客户端连接数
maxmemory <bytes>:最大内存使用容量,超出时按照maxmemory-policy设置的策略删除键值
maxmemory-policy noeviction:淘汰策略volatile-lru:从接近过期时间的键值中采用LRU算法淘汰 allkeys-lru:从所有键值中采用LRU算法淘汰 volatile-random:从接近过期时间的键值中随机淘汰 allkeys-random:从全部键值中随机淘汰 volatile-ttl:从最接近过期时间的键值开始淘汰 noeviction:不删除键值,写操作直接报错
maxmemory-samples 5: 淘汰算法运行时的采样样本数
SlowLog相关的配置:
slowlog-log-slower-than 10000:超过多少时间被记录进慢查询日志,单位是微秒
slowlog-max-len 128:慢查询日志最大条目Advanced配置:
hash-max-ziplist-entries 512:设置ziplist的键数量最大值
hash-max-ziplist-value 64:每个值的最大空间
client-output-buffer-limit normal 0 0 0:普通客户端输出缓冲限制
client-output-buffer-limit slave 256mb 64mb 60:从服务器客户端输出缓冲限制
client-output-buffer-limit pubsub 32mb 8mb 60:队列客户端输出缓冲限制
三个值的说明:<hard-limit> <soft-limit> <soft-limit seconds>,一般情况不能超过<soft-limit>,任何情况绝对不能超过<hard-limit>,超过<soft-limit>的部分在<soft-limit seconds>的宽限期后将被删除
四、Redis的持久化
(一)持久化的两种方式
RDB:snapshotting,二进制格式
按事先定制的策略,周期性地将数据从内存同步至磁盘
数据文件默认为dump.rdb
客户端显式使用SAVE或BGSAVE命令来手动启动快照保存机制
SAVE:同步,即在主线程中保存快照,此时会阻塞所有客户端请求
BGSAVE:异步,后台执行AOF:Append Only File, fsync
记录每次写操作至指定的文件尾部实现的持久化
当redis重启时,可通过重新执行文件中的命令在内存中重建出数据库
BGREWRITEAOF:AOF文件重写,后台执行
不会读取正在使用AOF文件,而是通过将内存中的数据以命令的方式保存至临时文件中,完成之后替换原来的AOF文件RDB模式效率更高,AOF模式时间精度更高
(二)RDB相关的配置:
-
save <seconds> <changes>
save 900 1 save 300 10 save 60 10000
表示:三个策略满足其中任意一个均会触发SNAPSHOTTING操作,即:
900s内至少有一个key有变化
300s内至少有10个key有变化
60s内至少有1W个key发生变化 stop-writes-on-bgsave-error yes
dump操作出现错误时,是否禁止新的写入操作请求,默认yesrdbcompression yes:复制时是否支持压缩,默认yes
rdbchecksum yes:复制时是否检验完整性,默认yes
dbfilename dump.rdb:指定rdb文件名
dir /var/lib/redis:rdb文件的存储路径
(三)AOF相关的配置
appendonly no:是否打开AOF模式,默认no
appendfilename "appendonly.aof":指定rof文件名
appendfsync:AOF同步模式,支持三种模式
no:不执行主动同步操作,而是OS进行
everysec:每秒一次
always:每语句一次no-appendfsync-on-rewrite no
是否在后台执行aof重写期间不调用fsync,默认为no,表示调用auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
上述两个条件同时满足时,方会触发重写AOF,即
与上次aof文件大小相比,其增长量超过100%,且大小不少于64MBaof-load-truncated yes
(四)其他
注意:持久机制本身不能取代备份;应该制订备份策略,对redis库定期备份;
RDB与AOF同时启用:
BGSAVE和BGREWRITEAOF不会同时进行
Redis服务器启动时用持久化的数据文件恢复数据,会优先使用AOF
五、Redis的复制
(一)特点:
- 一个Master可以有多个Slave主机,支持链式复制
- Master以非阻塞方式同步数据至Slave主机
(二)方法一:配置slave节点
- redis-cli> SLAVEOF <MASTER_IP> <MASTER_PORT>:指明主节点的IP和端口
- redis-cli> CONFIG SET masterauth <PASSWORD>:主节点密码认证
(三)方法二:配置参数
(1)必须配置的参数
- slaveof
- masterauth
(2)其他视情况配置的参数
slave-serve-stale-data yes:从节点是否使用过时的数据提供服务,默认yes
slave-read-only yes:从节点是否只读,默认yes
-
repl-diskless-sync no:是否使用无盘方式复制,由以下三种模式
no, Disk-backed, Diskless- 新的从节点或某较长时间未能与主节点进行同步的从节点重新与主节点通信,需要做"full synchronization",此时其同步方式有两种style:
- Disk-backend:主节点新创建快照文件于磁盘中,而后将其发送给从节点
- Diskless:主节点新创建快照后直接通过网络套接字文件发送给从节点
repl-diskless-sync-delay 5
当使用Diskless模式时,为了实现并行复制,通常需要在复制启动前延迟一个时间段,默认5srepl-ping-slave-period 10:从节点向主节点发送ping的间隔,默认10s
repl-timeout 60:复制超时时间,默认60s
repl-disable-tcp-nodelay no:是否禁用tcp延迟发送,默认不禁用
repl-backlog-size 1mb:消息队列长度
slave-priority 100
复制集群中,主节点故障时,sentinel应用场景中的主节点选举时使用的优先级
数字越小优先级越高,但0表示不参与选举min-slaves-to-write 3
主节点仅允许其能够通信的从节点数量大于等于此处的值时接受写操作min-slaves-max-lag 10
从节点延迟时长超出此处指定的时长时,主节点会拒绝写入操作
(四)实验1:实现Redis的复制
- 实验环境:
主节点IP:192.168.136.230
从节点1的IP:192.168.136.130
从节点2的IP:192.168.136.131
(1)编辑主从节点的配置文件,修改监听IP,配置密码认证
vim /etc/redis.conf
bind 0.0.0.0
requirepass centos
(2)编辑从节点1的配置文件
slaveof 192.168.136.230 6379 // 指向主节点的IP和端口
masterauth centos // 主节点的认证密码
(3)通过redis-cli命令配置从节点2的设置
redis-cli -h 192.168.136.131
192.168.136.131:6379> AUTH centos
192.168.136.131:6379> SLAVEOF 192.168.136.230 6379 // 指向主节点的IP和端口
192.168.136.131:6379> CONFIG SET masterauth centos // 主节点的认证密码
192.168.136.131:6379> CONFIG GET masterauth
192.168.136.131:6379> CONFIG GET slave-read-only
192.168.136.131:6379> CONFIG REWRITE // 写入配置文件
(4)启动主次节点的服务,测试配置
主节点上查看连接的从节点:127.0.0.1:6379> CLIENT LIST
主节点查看Replication章节的信息,可以看到从节点的相关信息
从节点1查看Replication章节的信息,可以看到主节点IP和当前连接状态
从节点2查看Replication章节的信息,可以看到主节点IP和当前连接状态
主节点查看所有键
从节点1查看所有键,成功同步
从节点2查看所有键,成功同步
(五)sentinel
(1)sentinel简介
- 主要完成三个功能:监控、通知、自动故障转移
- 选举:流言协议(向网络内多台主机确认主节点是否宕机)、投票协议(少数服从多数)
(2)配置项
配置文件:/etc/redis.conf
port 26379:默认监听端口,26379
sentinel monitor <master-name> <ip> <redis-port> <quorum>
主节点IP和端口
<quorum>:表示sentinel集群的quorum机制,即至少有quorum个sentinel节点同时判定主节点故障时,才认为其是真的故障
s_down: subjectively down,主观宕机,单个sentinel服务器独自判定主节点是否宕机
o_down: objectively down,客观宕机,多个sentinel服务器投票决定主节点是否宕机sentinel auth-pass <master-name> <password> :主节点认证
sentinel down-after-milliseconds <master-name> <milliseconds>
监控到指定的集群的主节点异常状态持续多久方才将标记为“故障”sentinel parallel-syncs <master-name> <numslaves>
指在failover过程中,能够被sentinel并行配置的从节点的数量;sentinel failover-timeout <master-name> <milliseconds>
sentinel必须在此指定的时长内完成故障转移操作,否则,将视为故障转移操作失败sentinel notification-script <master-name> <script-path>
通知脚本,此脚本被自动传递多个参数
(3)命令行选项
redis-cli -h SENTINEL_HOST -p SENTINEL_PORT
SENTINEL masters:查看主节点
SENTINEL slaves <MASTER_NAME>:查看指定主节点的从节点
SENTINEL failover <MASTER_NAME>
SENTINEL get-master-addr-by-name <MASTER_NAME>
(六)实验2:实现sentinel监控主机状态,当主节点发生故障时自动转移
- 实验环境:
继承实验1的主从节点环境,为减少实验系统开销,主节点、从节点1、从节点2共三台主机全部兼任sentinel服务器
根据quorum机制,只有大于过半数的节点认定主节点宕机才会视作主机宕机,故quorum值为2
(1)编辑三台主机的sentinel配置文件
vim /etc/redis-sentinel.conf
bind 0.0.0.0
sentinel monitor mymaster 192.168.136.230 6379 2
sentinel auth-pass mymaster centos
sentinel down-after-milliseconds mymaster 30000
(2)启动redis-sentinel服务,并测试
systemctl start redis-sentinel
登录sentinel服务器
redis-cli -h 192.168.136.230 -p 26379
SENTINEL masters // 查询主节点信息
SENTINEL slaves mymaster // 查询从节点信息
SENTINEL masters,查询主节点信息,当前为192.168.136.230,符合预期
SENTINEL slaves mymaster,查询从节点信息,当前为192.168.136.130和192.168.136.131,符合预期
(3)关闭主节点的redis服务,造成宕机状况,测试故障转移功能
systemctl stop redis // 192.168.136.230主机上操作
redis-cli -h 192.168.136.131 -p 26379
SENTINEL masters // 查询主节点信息
SENTINEL slaves mymaster // 查询从节点信息
192.168.136.130已经变为主节点
192.168.136.230已经降为从节点,由于宕机目前不可用
192.168.136.131仍旧保持从节点的身份
(4)修复主机192.168.136.230,并重新上线
vim /etc/redis.conf
slaveof 192.168.136.130 6379 // 设置为新的主节点IP
masterauth centos
systemctl start redis
成功上线
六、Redis的集群
(一)redis的集群技术:
Twitter:twemproxy,Twitter已经不再使用
豌豆荚:codis
原生:redis cluster
(二)redis cluster集群相关的配置:
- cluster-enabled
是否开启集群配置 - cluster-config-file
集群节点集群信息配置文件,每个节点都有一个,由redis生成和更新,配置时避免名称冲突 - cluster-node-timeout
集群节点互连超时的阈值,单位毫秒 - cluster-slave-validity-factor
进行故障转移时,salve会申请成为master。有时slave会和master失联很久导致数据较旧,这样的slave不应该成为master。这个配置用来判断slave是否和master失联时间过长。
(三)实验3:实现redis集群
- 提示:注意关闭之前实验的sentinel服务,将主从节点的相关配置恢复,然后重启redis服务
(1)设置配置文件,启用集群功能
vim /etc/redia.conf // 每个节点都要如此设置
cluster-enabled yes
cluster-config-file nodes-6379.conf
systemctl restart redis
(2)启动redis后为每个节点分配slots
systemctl restart redis
redis-cli -h 192.168.136.230 -a centos CLUSTER ADDSLOTS {0..5461}
redis-cli -h 192.168.136.130 -a centos CLUSTER ADDSLOTS {5462..10923}
redis-cli -h 192.168.136.131 -a centos CLUSTER ADDSLOTS {10924..16383}
注意:每个slot要独立创建;可用范围是0-16383,共16384个
使用CLUSTER INFO
查看集群信息,可以看到已经分配相应数量的slot,但是集群状态还是fail
(3)设定集群成员关系
redis-cli -h 192.168.136.230 -a centos
CLUSTER MEET 192.168.136.130 6379
CLUSTER MEET 192.168.136.131 6379
CLUSTER INFO
再次使用CLUSTER INFO
查看集群信息,集群状态已经ok状态
(4)测试集群功能
redis-cli -h 192.168.136.230 -a centos
192.168.136.230:6379> SET testkey1 hi
OK
192.168.136.230:6379> SET testkey2 hello
(error) MOVED 14758 192.168.136.131:6379
// 返回结果要求到192.168.136.131的节点执行操作
redis-cli -h 192.168.136.131 -a centos
192.168.136.131:6379> SET testkey2 hello
OK
192.168.136.131:6379> SET testkey3 sayhello
(error) MOVED 10631 192.168.136.130:6379
192.168.136.230成功存储testkey1键值对,但是节点要求去192.168.136.131存储testkey2键值对
192.168.136.131成功存储testkey2键值对,但是节点要求去192.168.136.130存储testkey3键值对
注意:当对redis cluster中的某个节点写数据时,可能会要求存储至其他节点。即可以向任意一个节点发起请求,节点可能会接收请求,也可能返回去其他节点完成操作的结果。故实际使用中,redis cluster需要与智能客户端协同发挥功能。