Redis
一、概述
1. 特点
- 开源的,使用c编写,基于内存且支持持久化
- 高性能的Key-Value的NoSQL数据库
- 支持数据类型丰富(字符串string、散列hashes、列表list、集合sets、有序集合sorted)
- 支持多种语言
2. 区别
- MySQL:关系型数据库,表格,基于磁盘,慢
- MongoDB:键值对文档型数据库,值为json文档,基于磁盘,慢,存储数据库类型单一
- Redis:解决硬盘IO带来的性能瓶颈
3. 应用场景
- 使用Redis来缓存一些经常被用到或者主要消耗大量资源的内容,通过这些内容放到Redis里面,程序可以快速读取这些内容
- 一个网站,如果某个页面经常被访问到,或者创建页面时消耗的资源较多,比如需要多次访问数据库、生成时间比较长等,我们可以使用Redis将其缓存起来,减轻网站负担,降低网站延迟
4. 附加功能
持久化
将内存中数据保存到磁盘中,保证数据安全,方便进行数据备份和恢复
发布与订阅
将消息同时分发给多个客户端,用于构建广播系统
过期键功能
为键设置一个过期时间,让他在指定时间内自动删除
事务功能
原子的多个操作
5. 安装
Ubuntu
sudo apt-get redis-server
Windows
前往GitHub下载Windows安装包,Redis官网并没有Windows版本的。
服务配置
将redis.windows.conf重命名为redis.conf,作为redis服务的配置文件
cmd命令行,切换到redis-server.exe目录
redis-server --service-install redis.conf --loglevel verbose
计算机-管理-服务-Redis-启动
卸载
到redis-server.exe所在路径执行
redis-server --service-uninstall
sc delete Redis
CentOS
CentOS安装Redis
二、基本配置
1. 密码配置
进入配置文件,查找
requirepass
后边加上密码重启服务
sudo /etc/init.d/redis-server restart
客户端连接
redis-cli -h 127.0.0.1 -p 6379 -a 123456
ping
2. 允许远程
vim /etc/vim /etc/redis/6379.conf
#注释bind 127.0.0.1 ::1
#将protected-mode yes 改为 protected-mode nobash
redis-cli -h IP -p 6379 -a passworld
三、数据类型
1. 字符串
特点
- 字符串、数字,都会转换为字符串来存储
命令
set key value #设置键值对
setnx key value #键不存在时才能设置
#设置过期时间
set key value ex 5 #以秒为单位
expire key 5 #在创建的时候并没有指定时间
mset key1 value1 key2 value2 #一次性设置多个值
mget key1 key2 key3 #同时获取多个值
键的命名规范
利用:层级关系
127.0.0.1:6379> mset zhang:email [email protected] li:email [email protected]
OK
127.0.0.1:6379> mget zhang:email li:email
1) "[email protected]"
2) "[email protected]"
1.1 长度
作用:获取值的长度
命令格式:strlen key
127.0.0.1:6379> get name
"danni"
127.0.0.1:6379> strlen name
(integer) 5
1.2 替换
setrange key 索引值 value
作用:从索引值开始,value替换原内容(依次替换)
127.0.0.1:6379> set message "hello world"
OK
127.0.0.1:6379> setrange message 6 python
(integer) 12
127.0.0.1:6379> get message
"hello python"
1.3 切片
getrange key 起始值 终止值
作用:获取指定范围内的
127.0.0.1:6379> get message
"hello python"
127.0.0.1:6379> getrange message 0 4
"hello"
127.0.0.1:6379> getrange message 0 -1
"hello python"
1.4 拼接
append key "value"
追加后边的值
127.0.0.1:6379> set message "hello "
OK
127.0.0.1:6379> get message
"hello "
127.0.0.1:6379> append message "python"
(integer) 12
127.0.0.1:6379> get message
"hello python"
1.5 加
incrby key 步长
在原来的value上+步长
127.0.0.1:6379> set number 10
OK
127.0.0.1:6379> incrby number 5
(integer) 15
127.0.0.1:6379> get number
"15"
1.6 减
decrby key 步长
同上,为减法
127.0.0.1:6379> get number
"15"
127.0.0.1:6379> decrby number 5
(integer) 10
127.0.0.1:6379> get number
"10"
1.7 浮点型
INCRBYFLOAT key value
加法,如果value为负数,则为减法
127.0.0.1:6379> get number
"18"
127.0.0.1:6379> INCRBYFLOAT number 6.66
"24.66"
127.0.0.1:6379> INCRBYFLOAT number -6.66
"18"
1.8 汇总
#字符串
1、set key value
2、setnx key value
3、get key
4、mset key1 value1 key2 value2
5、mget key1 key2
6、set key value ex seconds # 设置过期时间
7、strlen key
#数字操作
8、incrby key 步长
9、decrby key 步长
10、incr key
11、decr key
12、incrbyfloat key number
#设置过期时间的两种方式
#方式一
1、set key value ex 3
#方式二
1、set key value
2、expire key 3 #秒
3、pexpire key 5 #毫秒
#查看存活时间
ttl key
# 删除过期
persist key
1.9 通用命令
# 查看所有键
keys *
# 键类型
type key
# 键是否存在
exists key
# 删除键
del key
# 键重命名
rename key newkey
# 返回旧值并设置新值(如果键不存在,就会创建并赋值)
getset key value
# 清除当前库中的所有数据
flushdb
# 清除所有库中的所有数据
flushall
1.10 练习
- 查看db0中的所有键
select 0
keys *
- 设置键trill::username 对应的值为user001,并查看
set trill::username user001
- 获取trill::username 值长度
strlen trill::username
- 一次性的设置trill::password、trill::gender、trill::fansnumber并查看(值自定义)
mset trill::password 123456 trill::gender boy trill::fansnumber 100
- 查看键trill::score是否存在
exsits trill::score
- 增加10个粉丝
incrby trill::fansnumber 10
- 增加2个粉丝
incr trill::fansnumber
incr trill::fansnumber
- 减少3个粉丝
decrby trill::fansnumber 3
- 又有一个粉丝减少
decr trill::fansnumber
- 清除当前库
fulshdb
- 清除所有库
fulshall
2. 列表
特点:
2.1 插入
头尾压入元素
lpush key value1 value2 value3
头部压入数据
rupsh key value1 value2 value3
尾部压入数据
# lpush :left
127.0.0.1:6379> lpush mylist1 0 1 2 3 # 该表为["lucy", "tom", "10"]
127.0.0.1:6379> lrange mylist1 0 -1
1) "3"
2) "2"
3) "1"
4) "0"
# rpush:right
127.0.0.1:6379> rpush mylist2 0 1 2 3
(integer) 4
127.0.0.1:6379> lrange mylist2 0 -1
1) "0"
2) "1"
3) "2"
4) "3"
2.2 查看
lrange
# lrange key start stop
lrange mylist1 0 2 # 显示前三个元素
lrange mylist1 0 -1 # 显示全部元素
lindex
获取指定位置元素的值
127.0.0.1:6379> lrange mylist1 0 -1
1) "3"
2) "2"
3) "1"
4) "0"
127.0.0.1:6379> lindex mylist1 1
"2"
lset
替换元素
127.0.0.1:6379> lrange mylist1 0 -1
1) "3"
2) "2"
3) "1"
4) "0"
127.0.0.1:6379> lset mylist1 1 tom
OK
127.0.0.1:6379> lrange mylist1 0 -1
1) "3"
2) "tom"
3) "1"
4) "0"
llen
获取列表长度
127.0.0.1:6379> lrange mylist1 0 -1
1) "3"
2) "2"
3) "1"
4) "0"
127.0.0.1:6379> llen mylist1
(integer) 4
2.3 删除
头尾弹出元素
lpop key
从列表的头部弹出一个元素
127.0.0.1:6379> lrange mylist1 0 -1
1) "3"
2) "2"
3) "1"
4) "0"
127.0.0.1:6379> lpop mylist1
"3"
127.0.0.1:6379> lrange mylist1 0 -1
1) "tom"
2) "1"
3) "0"
rpop key
从列表的尾部弹出一个元素
127.0.0.1:6379> lrange mylist1 0 -1
1) "tom"
2) "1"
3) "0"
127.0.0.1:6379> rpop mylist1
"0"
127.0.0.1:6379> lrange mylist1 0 -1
1) "tom"
2) "1"
rpoprpush
rpoprpush list1 list2
弹出list1尾部元素并压入list2尾部(可自由组合)
127.0.0.1:6379> rpush mylist1 0 1 2 3 4
(integer) 5
127.0.0.1:6379> rpoplpush mylist1 mylist2
"4"
127.0.0.1:6379> lrange mylist2 0 -1
1) "0"
2) "1"
3) "2"
4) "3"
127.0.0.1:6379> lrange mylist2 0 -1
1) "4"
lrem
lrem key count vlaue
移除指定元素()
count > 0
表示从头开始向表尾搜索,移除与value相等的元素,删除的数量为count
count < 0
表示从尾开始向表头搜索,移除与value相等的元素,删除的数量为|count|
count = 0
表示删除所有value值
127.0.0.1:6379> lrange mylist 0 -1
1) "6"
2) "5"
3) "4"
4) "chancey"
5) "2"
6) "waller"
7) "0"
8) "chancey"
9) "1"
10) "waller"
11) "3"
127.0.0.1:6379> lrem mylist 1 chancey
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "6"
2) "5"
3) "4"
4) "2"
5) "waller"
6) "0"
7) "chancey"
8) "1"
9) "waller"
10) "3"
127.0.0.1:6379> lrem mylist -2 waller
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "6"
2) "5"
3) "4"
4) "2"
5) "0"
6) "chancey"
7) "1"
8) "3"
ltrim
ltrim key start stop
保留指定位置的元素
127.0.0.1:6379> lrange mylist1 0 -1
1) "tom"
2) "0"
3) "1"
4) "2"
5) "3"
6) "4"
127.0.0.1:6379> ltrim mylist1 0 1 # 保留前两位元素
OK
127.0.0.1:6379> lrange mylist1 0 -1
1) "tom"
2) "0"
#保留微博最后500条评论
ltrim weibo:comments 0 499
ltrim weibo:comments -500 -1
练习
- 查看所有的键
key *
- 向列表 spider::urls 中已rpush放入如下元素(01_baidu.com、02_taobao.com、03_sina.com、04_jd.com、05_xxx.com)
rpush spider::urls 01_baidu.com、02_taobao.com、03_sina.com、04_jd.com、05_xxx.com
- 查看列表中的所有元素
lrange spider::urls
- 查看列表长度
llen spider::urls
- 将列表中01_baidu.com 改为01_tmall.com
lset sipder::urls 0 01_tmall.com
- 在列表中04_jd.com之后再加一个元素02_tabao.com
linsert spider::urls after 04_jd.com 02_taobao.com
- 弹出列表中的最后一个元素
rpop spider::urls
- 删除列表中所有的02_taobao.com
lrem spider::urls 0 02_taobao.com
- 剔除列表中的其他元素,只剩前三条
ltrim spider::urls 0 2
2.4 汇总
# 插入元素的相关操作
lpush key value1 value2
rpush key value1 value2
rpoplpush course destination
linsert key after | before value newvalue
# 查询相关的操作
lrange key start stop
llen key
# 删除相关操作
lpop key
rpop key
blpop key timeout # timeout参数必须给,0为永久阻塞
brpop key timeout # 同上
lrem key count value # 剔除count个value
ltrim key start stop # 保留范围内元素
# 修改制定元素
lset key index newvalue
Redis列表如何当做共享队列来使用?
- 生产者消费者模型
- 生产者进程在列表中 lpush | rpush 数据,消费者进程在列表中 rpop | lpop 数据
==位图操作==
特殊的字符串类型
- 位图不是真正的数据类型,他是定义在字符串类型中
- 一个字符串类型的值最多嫩存储512M字节的内容(位上线)
常用命令
# 设置某一位上的值,offset是偏移量,从0开始
setbit key offset value
# 获取某一位上的值
getbit key offset
# 统计键所对应的值中有多少个,二进制中1的格式
bitcount key
应用场景
网站用户的上线次数统计(寻找活跃用户)
用户名为key,上线天数为offset,上线设置为1
示例:用户名为user001的用户,今年第1天上线,第30天上线
setbit user 001 setbit user 29 1 bitcount user001
python文件
import redis r = redis.Redis(host="127.0.0.1", port=6379, db=0) #user1:一年之中第一天和第五天登录 r.setbit("user1", 0, 1) r.setbit("user1", 4, 1) #user2:一年之中第100天和第200天登录 r.setbit("user2", 99, 1) r.setbit("user2", 199, 1) #user3:一年中有100天以上登录 for i in range(0, 365, 2): r.setbit("user3", i, 1) #user4:一年中有100天以上登录 for i in range(0, 365, 3): r.setbit("user4", i, 1) #统计活跃用户和非活跃用户 ## 先找到所有用户 user_list = r.keys("user*") ## 定义两个列表,活跃用户和非活跃用户 active_users = [] no_active_users = [] for user in user_list: # 统计位图中有多少个1 login_count = r.bitcount(user) if login_count >= 100: active_users.append((user, login_count)) else: no_active_users.append((user, login_count)) #打印活跃用户 #活跃用户: [(b'user4', 122), (b'user3', 183)] for user in active_users: print("活跃用户:%s 活跃次数:%s" % (user[0].decode(), user[1]))
3. 散列
3.1 概述
3.1.1 定义
3.2.1 优点
- 节约内存空间
- 每创建一个键,他都会为这个键存储一些附加的管理信息(比如这个键的类型,这个键最后一次访问的事件等)
- 键越多,redis数据库在存储附件管理信息方面耗费内存越多,花在管理数据库键上的CPU也会越多
3.2.2 缺点
- 使用二进制位操作命令:
setbit
、getbit
、bitcount
等,如果想使用这些操作,只能用字符串键 - 使用过期功能:键过期功能只能对键进行过期操作,而不能对散列的字段进行过期操作
3.2 基本命令
# 1、设置单个字段
hset key filed value
hsetnx key filed value
# 2、设置多个字段
hmset key filed value filed value
# 3、返回字段个数
hlen key
# 4、判断字段是否存在(不存在返回0)
hexists key field
# 5、返回字段值
hget key field
# 6、返回多个字段值
hmget key field1 filed2
# 7、返回所有键值对
hgetall key
# 8、返回字段长度
hlen key
# 9、返回所有字段名
hkeys key
# 10、返回所有值
hvals key
# 11、删除指定字段
hdel key field1 field2 field3
# 12、在字段对应值上进行整数增量运算
hincrby key filed increment
# 13、在字段对应值上进行浮点数增量运算
hincrbyfloat key filed increment
4. 集合
与python集合类似
4.1 概述
4.2 基本命令
# 1、增加一个或多个元素,自动去重
sadd key member1 member2
# 2、查看集合中所有元素
smembers key
# 3、删除一个或多个元素,元素不存在则自动忽略
sismember key count
# 4、随机弹出元素(默认弹出一个)
spop key [count]
# 5、元素是否存在(返回1表示存在,0表示不存在)
sismember key member
# 6、随机返回集合中指定个数的元素,默认一个
srandmember key count
# 7、返回集合中元素的个数,不会遍历整个集合,只是存储在键当中
scard key
# 8、把元素从源集合移动到目标集合
smove source desctination member
# 9、差集(number1 1 2 3 4 number2 1 2 4)
sdiff key1 key2
sdiffstore destination key1 key2 #将差集保存至新集合里
# 10、交集
sinter key1 key2
sinserstore destination key1 key2 #同上
# 11、并集
sunion key1 key2
sunionstore destination key1 key2 #同上
sina的共同关注
需求:当用户访问另一个用户的时候,会显示出两个用户共同关注过哪些相同的用户
设计:将每一个用户关注的用户放在集合,求交集即可
实现:
user001 = {"peiqi", "qiaozhi", "danni"}
user002 = {"peiqi", "qiaozhi", "lingyang"}
127.0.0.1:6379> sadd user001 peiqi qiaozhi danni (integer) 3 127.0.0.1:6379> sadd user002 peiqi qiaozhi lingyang (integer) 3 127.0.0.1:6379> sinterstore user_all user001 user002 1) "peiqi" 2) "qiaozhi"
6. 有序集合
即有顺序的集合
6.1 概述
示例:
一个保存的水果价格的有序集合
分值 | 2.0 | 4.0 | 6.0 | 8.0 | 10.0 |
---|---|---|---|---|---|
元素 | 西瓜 | 葡萄 | 芒果 | 香蕉 | 苹果 |
一个保存了员工薪水的有序集合
分值 | 6000 | 8000 | 10000 | 12000 |
---|---|---|---|---|
元素 | lucy | tom | jim | jack |
一个保存了正在阅读某些技术书的人数
分值 | 300 | 400 | 555 | 666 | 777 |
---|---|---|---|---|---|
元素 | 核心编程 | 阿凡提 | 本拉登 | 阿姆斯特朗 | 比尔盖茨 |
6.2 增加
zadd key score member
# 有序集合中添加一个成员
zadd key score member
# 查看指定区间元素(升序)
zrange key start stop [withscores]
# 查看指定区间元素(降序)
zrevrange key start stop [withscores] #反转
# 查看指定元素的分值
zscore key member
# 返回指定区间元素
# offset:跳过多少个元素
# count : 返回几个
# 小括号:开区间
zrangebyscore key min max [withscore] [limit offset count]
例如: zrangebyscore salary (6000 (8000 # 删除6000-8000之间的所有元素
# 删除成员
zrem key member
# 增加或者减少分值
zincrby key increment member
# 返回元素逆序排名
zrevrank key member
# 删除指定区间的元素
zremrangebyscore key min max
#返回集合中元素个数
zcard key
# 返回指定范围中元素的个数
zount key min max
# 并集 numkeys为想要合并的key的个数
zunionstore destination numkeys key [weights 权重值] [aggregate sum|min|max]
# 交集
zinterstore destination numkeys key1 key2 weights weight aggregate sum|min|max
6.3 交并集
# 交集(weights代表权重值,aggregate代表聚合方式 - 计算权重值,然后聚合)
zinserstore destination numkeys key1 key2
`zinterstore z_inter 2 z1 z2 weights 0.5 0.3 aggregate max`
# 并集
zunionstore destination numkeys [weights 权重值] [aggregate sum|min|max]
6.4 应用场景
网易云音乐排行榜
1、每首歌的革命作为元素(不考虑重复)
2、每首歌的播放次数作为分值
3、使用zrevrange来获取播放次数最多的歌曲
四、数据持久化
持久化:将数据库从掉电易失的内存放到永久储存的设备上
1. RDB
默认模式
- 保存真实的数据
- 将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘里面
- 默认文件名:
var/lib/redis/dump.rdb
创建RDB的方式有两种
1.1 手动操作
服务器执行客户端发送的save或者bgsave命令
127.0.0.1:6379> save
OK
127.0.0.1:6379> exit
chancey@Server:~$ sudo ls /var/lib/redis/
dump.rdb
- 特点
- 执行save命令过程中,redis服务器将被阻塞,无法处理客户端发送命令请求,在save之后,吴福气才会重新开始处理客户端发送的命令请求
- 如果RDB文件存在,那么服务器将自动使用新的RDB文件覆盖原来的RDB文件
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> exit
chancey@Server:~$ sudo ls -l /var/lib/redis/
总用量 4
-rw-rw---- 1 redis redis 581 9月 2 14:22 dump.rdb
执行过程如下
- 客户端发送bgsave给服务器
- server马上返回Background saving started 给client
- server 的 fork() 子进程做这件事情
- server继续提供服务
- 子进程创建完RDB文件后再告知Redis server
配置文件的相关操作
/etx/redis/redis.conf dir /var/lib/redis # 表示redis备份路径 dbfilename dump.rdb # 文件名
1.2 自动备份
设置配置文件条件满足时自动保存(使用最多)
# 命令行示例
redis>save 300 10
表示如果距离上一次创建的RDB文件已经过去了300秒,并且服务器的所有数据库总共发生了不少于10的修改,那么执行命令dbsave
配置文件默认设置
save 900 1
save 300 10
save 60 10000
1、表示只要三个条件中的任意一个被满足时,服务器就会执行bgsave
2、每次创建RDB文件之后,服务器为实现自动持久化而设置的事件计数器和次数计数器就会被清零,并重新开始计数,所以多个保存条件的效果不会叠加
1.3 缺点
- 创建RDB文件需要将server所有的数据库数据保存,其过程非常消耗资源和时间,所有server需要隔一段时间才创建一个新的RDB文件,也就是说,创建RDB文件不能执行的过于频繁,否则会严重影响server的性能
- 可能丢失数据
2. AOF
2.1 配置
存储的是命令,而不是真实的数据
默认不开启
开启方式:
/etc/redis/redis.conf
改
appendonly no
为appendonly yes
改
#appendfilename "appendonly.aof"
为appendfilename "appendonly.aof"
sudo /etc/init.d/redis-server restart
重启服务
2.1 原理
- 每当有修改数据库的命令被执行的时候,server就会将执行的命令写到AOF文件的末尾
- 因为AOF文件里面存储了server执行过的所有数据修改的命令。所以给定一个AOF文件,服务器只要重新执行一遍AOF文件里面的所有命令,就可以达到还原数据的目的
2.2 优点
用户可以根据自己的需要对AOF持久化进行调整,让Redis在遭遇意外停电停机时不会丢失任何数据,或者只丢失一秒的数据
2.3 策略
编辑配置文件/etc/redis/redis.conf
appendfsync alwarys
服务器每写入一条命令,就将缓冲区里面的命令写入到硬盘里面,server就算意外停机,也不会丢失人格已经成功执行的命令
appendfsync everysec #(默认)
server每一秒将缓冲区里面的命令写入到硬盘里面,服务器即使遭受意外停机,最多丢失一秒的数据
appendfsync no
server不主动将命令写入硬盘。由操作系统决定何时将缓冲区里面的命令写入到硬盘里面,丢失命令数量不确定
AOF中的冗余命令
为了让AOF文件的大小控制在合理范围,避免胡乱增长,redis提供了AOF重写功能,通过这个功能,server可以产生一个新的AOF文件
-- 新的AOF文件记录的数据库数据和原来的AOF文件记录的数据库数据完全一样
-- 新的AOF文件会使用尽可能少的命令记录数据数据,因此新的AOF文件的体积通常会小很多
-- AOF重写期间,服务器不会阻塞,可以正常处理客户端发送的命令请求
2.4 重写触发
client向server发送
bgrewriteaof
127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started
修改配置文件让server自动执行bgrewriteaof命令
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
只有当AOF文件的增量大于100%时才进行重写,也就是大一倍的时候触发
3. 总结
配置文件:/etc/redis/redis.conf
日志文件:/var/log/redis/reids-server.log
RDB文件:/var/lib/redis/dump.rdb
AOF文件:/var/lib/redis/appendonly.aof
3.1 RDB
默认
dir /var/lib/redis
dbfilename dumo.rdb
save 900 1
save 300 10
save 60 10000
3.2 AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync always
appendfsync everysec
appendfsync no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
五、主从复制
1. 概述
定义
- 一个redis服务可以有多个该服务的复制品,这个redis称为master,其他复制品称为slaves
- 网络正常,master会一致将自己的数据更新同步给slaves,保持主从同步
- 只有master可以执行写命令,slave只能执行读命令
作用
- 分担了读的压力(高并发)
原理
- 从服务器执行客户端发送的读命令,比如GET、LRANGE、SMEMMVERS、HGET、ZRANGE等等,客户端可以连接slaves执行读请求,来降低master的读压力
2. 实现
==法一(命令行)==
redis-server --port 630 --slaveof 127.0.0.1 6379
# 从server端
redis-server --port 6300 --slaveof 127.0.0.1 6379
# 从client端
redis-cli -p 6300
127.0.0.1:6300> keys *
# 发现是复制了原6379端口的redis数据
127.0.0.1:6379> set sex man
OK
127.0.0.1:6300> keys *
1) "name"
2) "sex"
# 从server只能读取数据,不能写入`
==法二(命令行)==
127.0.0.1:6379> keys *
1) "name"
2) "sex"
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> slaveof 127.0.0.1 6379 # 切换为从server
OK
127.0.0.1:6379> set newkey 456
(error) READONLY You can't write against a read only slave.
127.0.0.1:6379> keys *
1) "age"
2) "name"
3) "sex"
127.0.0.1:6379> slaveof no one # 切换回主server
OK
==法三(修改配置)==
vim /etc/redis/redis.conf