2019独角兽企业重金招聘Python工程师标准>>>
一. 主从复制
1. 结构模式
- 一主一从
- 一主多从
- 主丛从
2. 工作原理
- slave向master发送sync命令。
- master启动后台存盘进程,并收集所有修改数据命令。
- master完成后台存盘后,传送整个数据文件到slave。
- slave接收数据文件,加载到内存中完成首次完全同步。
- 后续新数据产生,master继续将新的数据收集到的修改命令依次传给slave,完成同步。
3. 缺点
- 网络和系统繁忙时,会产生数据同步延时。
4. 一主一从配置
默认所有的Redis服务器都是主库,只需要配置从库。
默认从库都是只读的,不能插入数据。
(1) 查看主从配置信息:主库登陆redis后输入info replication
info replication# Replicationrole:masterconnected_slaves:0 //没有从库master_replid:dc2cd3bb9200687f7e20749128614ab43ca310dcmaster_replid2:0000000000000000000000000000000000000000master_repl_offset:0second_repl_offset:-1repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
(2) 从库上配置:slaveof 主库IP 主库端口号
slaveof 192.168.4.51 6351
(3) 再次在主库上查看主从配置信息
info replication# Replicationrole:masterconnected_slaves:1 //一个从库slave0:ip=192.168.4.52,port=6352,state=online,offset=210,lag=1master_replid:d4296cbb0f2298172be749620e7b47b5e8d696damaster_replid2:0000000000000000000000000000000000000000master_repl_offset:224second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:224
5. 一主多从配置(主从从方法类似)
(1) 在第二台从库上输入slaveof 命令
slaveof 192.168.4.51 6351
(2) 再次在主库上查看主从配置信息
info replication# Replicationrole:masterconnected_slaves:2 //两个从库slave0:ip=192.168.4.52,port=6352,state=online,offset=476,lag=1slave1:ip=192.168.4.53,port=6353,state=online,offset=476,lag=1master_replid:d4296cbb0f2298172be749620e7b47b5e8d696damaster_replid2:0000000000000000000000000000000000000000master_repl_offset:490second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:490
6. 从库恢复为独立数据库
(1) 重启服务
/etc/init.d/redis_6379 stop
/etc/init.d/redis_6379 start
(2) slaveof no one
7. 永久配置主从配置
修改配置文件,282行取消注释。
/etc/init.d/redis_6379 stopvim /etc/redis/6379.conf282 slaveof 192.168.4.51 6351/etc/init.d/redis_6379 start
8. 配置带密码验证的主从同步
(1) 主库修改密码,配置文件501行。重启服务。
/etc/init.d/redis_6379 stopvim /etc/redis/6379.conf 501 requirepass 123456/etc/init.d/redis_6379 start
(2) 从库修改配置文件,配置文件289行修改密码。重启服务。
/etc/init.d/redis_6379 stopvim /etc/redis/6379.conf 289 masterauth 123456/etc/init.d/redis_6379 start
9. 哨兵模式
- 主库宕机后,从库自动升级为主库。
(1) 从库主机编辑sentinel.conf文件。(模板在源码包中)
vim /etc/sentinel.confsentinel monitor redis51 192.168.4.51 6351 1#sentinel monitor 主机名 IP地址 端口 票数#票数:有机态哨兵主机连接不上主库时,切换主库。sentinel auth-pass redis51 123456
(2) 从库上运行哨兵程序。(程序将占用该终端)
redis-sentinel /etc/sentinel.conf
#以下为输出信息
2567:X 27 Aug 10:51:24.793 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2567:X 27 Aug 10:51:24.793 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=2567, just started
2567:X 27 Aug 10:51:24.793 # Configuration loaded
2567:X 27 Aug 10:51:24.795 * Increased maximum number of open files to 10032 (it was originally set to 1024)._._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.8 (00000000/0) 64 bit.-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in sentinel mode|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379| `-._ `._ / _.-' | PID: 2567`-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 2567:X 27 Aug 10:51:24.796 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2567:X 27 Aug 10:51:24.833 # Sentinel ID is 7c618b1ca9bd3d7eca4ea9e909aa6246f4629544
2567:X 27 Aug 10:51:24.834 # +monitor master redis51 192.168.4.51 6351 quorum 1
2567:X 27 Aug 10:51:24.836 * +slave slave 192.168.4.52:6352 192.168.4.52 6352 @ redis51 192.168.4.51 6351
(3) 主库宕机后,从库将自动升级为主库。之前的主库恢复后,自动变为从库。
二. 持久化
1. RDB
(1) 介绍
- RDB,Redis DataBase, Redis数据库文件。
- 数据持久化方式之一,默认。
- 按照指定时间间隔,将内存的数据集快照(Snapshot)写入硬盘。
- 恢复时,将快照文件直接都入内存。
(2) 相关参数
- 文件名dump.rdb,在配置文件中配置,位于数据库目录中。
vim /etc/redis/6379.conf254 dbfilename dump.rdb
- 数据从内存保存到硬盘的频率在配置文件中定义。
vim /etc/redis/6379.conf219 save 900 1 #900秒有1次修改220 save 300 10 #300秒有10次修改221 save 60 10000 #60秒有10000次修改#该三行值可手动修改
- 手动立刻存盘
- save //阻塞写存盘
- bgsave //不阻塞写存盘
- 压缩:
242 rdbcompression yes #RDB文件是否压缩,默认开启。
- 存储快照后,使用crc16算法进行数据校验:
251 rdbchecksum yes #默认开启校验
- gbsave出错时是否停止写操作:
236 stop-writes-on-bgsave-error yes #默认bgsave出错时停止写操作
(3) 备份/恢复数据
备份:在数据库目录/var/lib/redis/6379中,备份dump.rdb文件。
cp dump.rdb dump.rdb.aaa #备份
恢复:将需要恢复的RDB文件拷贝到数据库目录中,重启Redis服务。
/etc/init.d/redis_6379 stop
cp dump.rdb.aaa dump.rdb #恢复
/etc/init.d/redis_6379 start
(4) RDB优缺点
优点:
- 高性能持久化实现:创建子程序执行持久化,先将数据写入临时文件,再替换RDB文件;主进程不做IO操作。
- 适合大规模数据恢复且对数据完整性要求不是非常高的场合。
缺点:
- 意外宕机时,最后一次持久化的数据会丢失。
2. AOF
(1) 介绍
- Append Only File,只做追加操作的文件
- 追加Redis的所有写操作到文件末尾
- 可以使用cat命令查看文件内容
(2) 相关参数
- 文件名:
/etc/init.d/redis_6379 stop
vim /etc/redis/6379.conf673 appendonly yes #启用aof,默认为no677 appendfilename "appendonly.aof" #aof文件名,启用后重启服务会在数据库文件夹中自动生成
/etc/init.d/redis_6379 start
- AOF文件记录写操作的方式:
703 appendfsync everysec #每秒记录一次,默认。# appendfsync always #有新的写操作立刻记录# appendfsync no #从不记录。服务本身不记录,等待操作系统记录。
- 触发日志文件重写:(将重复的操作进行合并)
744 auto-aof-rewrite-percentage 100
745 auto-aof-rewrite-min-size 64mb #每到64M整理一次
- 修复AOF文件:
- 当RDB和AOF同时存在时,AOF优先。
- 把文件恢复到最后一次正确的操作。
手动破坏AOF文件,启动服务会失败:
redis-cli -p 6354 -h 192.168.4.54
Could not connect to Redis at 192.168.4.54:6354: Connection refused
Could not connect to Redis at 192.168.4.54:6354: Connection refused
修复AOF文件:
redis-check-aof --fix appendonly.aof
0x 107: Expected prefix '*', got: 'f'
AOF analyzed: size=284, ok_up_to=263, diff=21
This will shrink the AOF from 284 bytes, with 21 bytes, to 263 bytes
Continue? [y/N]: y #回车
Successfully truncated AOF
再次启动服务时会报错:
/etc/init.d/redis_6379 start
/var/run/redis_6379.pid exists, process is already running or crashed #报错,pid文件已存在,需要删除
删除pid文件重启服务:
rm -rf /var/run/redis_6379.pid #删除pid文件
/etc/init.d/redis_6379 start #再次启动服务
Starting Redis server... #服务正常启动
(3) AOF优缺点
优点:
- 可灵活设置持久化方式,同步持久化(appendfsync always)或异步持久化(appendfsync everysec)
- 出现意外宕机,仅丢失1秒数据。
缺点:
- 持久化文件体积通常大于RDB方式
- 执行fsync策略速度可能比RDB慢
三. 数据类型
1. String字符串操作
(1) 插入 set/mset
set key value [ex seconds] [px milliseconds] [nx|xx]
- ex 设置过期时间,秒为单位
- px 设置过期时间,毫秒为单位
- nx 变量不存在时才创建,存在时不创建
- xx 不论变量是否存在都覆盖创建,默认
mset aa 1 bb 2 cc 3
(2) 复写特定位置的值 setrange
set first 'hello world'
setrange first 6 'Redis'
get first #输出"hello Redis"
(3) 统计字串长度 strlen
strlen first #输出 (integer) 11
(4) 追加 append
存在则追加,不存在则创建,返回key的长度。
append first (add) #输出(integer) 16
get first #输出"hello Redis(add)"
append second 222 #输出(integer) 3
(4) 按比特存储 setbit
- value的值可以为1或0,offset为0~2^32之间
- key不存在时则创建
- 节约空间
- bitcount 统计字符串中设置为1的比特数
setbit aaa 1 1
setbit aaa 2 1
setbit aaa 3 0
setbit aaa 4 0
setbit aaa 5 0
setbit aaa 6 1
setbit aaa 7 1
bitcount aaa #输出为4
(5) 变量值自减 decr/decrby (值必须为整数)
set a 100
decr a #输出为99
decrby a 20 #输出80
(6) 变量值自加 incr/incrby (值必须为整数)
set a 100
incr a #输出101
incrby a 20 #输出120
(7) 获取字符串值 get/mget
- 返回字符串值
- 如果key的值不是字符串,则返回错误
get abc
#输出"999"
mget a abc c
#输出
1) "100.5"
2) "999"
3) "110"
(8) 获取子字符串 getrange
set kkk ABCDEFG
getrange kkk 0 3
#输出"ABCD"
getrange kkk -2 -1
#输出"FG"
getrange kkk -1 -3
#输出""
2. List列表操作
- 字符串队列
- 先进后出
- 一个key可以有多个值
(1) 插入lpush
- 将一个或多个value值插入到key的表头
- key不存在则创建
(2) 输出lrange
lpush a 1 2 3 4
lrange a 0 1
#输出
1) "4"
2) "3"
lrange a 0 -2
#输出
1) "4"
2) "3"
3) "2"
lrange a 0 -1
#输出
1) "4"
2) "3"
3) "2"
4) "1"
(3) 返回key长度 llen
(4) 移除列表头元素,key不存在则返回nil
llen a
#输出4,表示长度为4
lpop a
#输出"4"
lpop a
#输出"3"
lpop a
#输出"2"
lpop a
#输出"1"
lpop a
#输出(nil)
(5) 返回某个位置的值 lindex
(6) 设置某个位置的值lset
lpush b A B C D E F
lindex b 0
#输出第一个值"F"
lindex b -1
#输出最后一个值"A"
lset b 1 EE #修改位于位置1的值为“EE”
(7) 将值插入key的尾部 rpush
(8) 删除并返回key尾部的值 rpop
rpush b G H #b的尾部插入“G”和“H”
lrange b 0 -1 #输出b所有的值
1) "F"
2) "EE"
3) "D"
4) "C"
5) "B"
6) "A"
7) "G"
8) "H"
rpop b #删除b末尾的值
"H"
lrange b 0 -1 #输出b所有的值
1) "F"
1) "F"
2) "EE"
3) "D"
4) "C"
5) "B"
6) "A"
7) "G"
3. Hash表操作
- string类型的field和value的映射表
- 一个key对应多个field,一个field对应一个value
- 节省内存
(1) 存储hset/取值hget
hset site baidu www.baidu.com
hset site google www.google.com
hget site baidu
#输出"www.baidu.com"
hget site google
#输出"www.google.com"
hget site aaa
#输出(nil)
(2) 多个存储hmset/取值hmget
hmset site 163 www.163.com sina www.sina.com
hmget site 163 sina
#输出
1) "www.163.com"
2) "www.sina.com"
(3) 返回所有的field值hkeys
(4) 返回所有的value值hvals
(5) 返回所有的值hgetall
hkeys site
#输出
1) "baidu"
2) "google"
3) "163"
4) "sina"
hvals site
#输出
1) "www.baidu.com"
2) "www.google.com"
3) "www.163.com"
4) "www.sina.com"
hgetall site
#输出
1) "baidu"
2) "www.baidu.com"
3) "google"
4) "www.google.com"
5) "163"
6) "www.163.com"
7) "sina"
8) "www.sina.com"
(6) 删除多个field值 hdel
hdel site google 163 aaa
hgetall site
#输出
1) "baidu"
2) "www.baidu.com"
3) "sina"
4) "www.sina.com"