学习交流群:817080571
Redis安装以及常用操作
Redis介绍
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis安装
Docker版
安装
docker pull redis
配置redis.conf
进入或者创建 /usr/local/docker/redis 目录下创建redis.conf
cd /usr/local/docker/redis
vim /usr/local/docker/redis/redis.conf
daemonize : 默认为no,修改为yes启用守护线程
port :设定端口号,默认为6379
bind :绑定IP地址
databases :数据库数量,默认16
save :指定多少时间、有多少次更新操作,就将数据同步到数据文件
#redis默认配置有三个条件,满足一个即进行持久化
save 900 1 #900s有1个更改
save 300 10 #300s有10个更改
save 60 10000 #60s有10000更改
dbfilename :指定本地数据库的文件名,默认为dump.rdb
dir :指定本地数据库的存放目录,默认为./当前文件夹
requirepass :设置密码,默认关闭
redis -cli -h host -p port -a password
运行
启动redis服务
docker run -p 6379:6379 -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data --name myredis -d redis
进入redis
docker exec -it redisID /bin/bash
运行redis
redis-cli
Linux版
后期更新
Windows版
后期更新,不推荐使用windows版,个人使用除外
Redis常用操作
Redis五大数据类型
Redis五种数据类型:string、hash、list、set、zset
公用命令
DEL key
DUMP key:序列化给定key,返回被序列化的值
EXISTS key:检查key是否存在
EXPIRE key second:为key设定过期时间
TTL key:返回key剩余时间
PERSIST key:移除key的过期时间,key将持久保存
KEY pattern:查询所有符号给定模式的key
RANDOM key:随机返回一个key
RANAME key newkey:修改key的名称
MOVE key db:移动key至指定数据库中
TYPE key:返回key所储存的值的类型
string(字符串)
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
常用命令
setkey_name value:命令不区分大小写,但是key_name区分大小写
SETNX key value:当key不存在时设置key的值。(SET if Not eXists)
get key_name
GETRANGE key start end:获取key中字符串的子字符串,从start开始,end结束
MGET key1 [key2 …]:获取多个key
GETSET KEY_NAME VALUE:设定key的值,并返回key的旧值。当key不存在,返回nil
STRLEN key:返回key所存储的字符串的长度
INCR KEY_NAME :INCR命令key中存储的值+1,如果不存在key,则key中的值话先被初始化为0再加1
INCRBY KEY_NAME 增量
DECR KEY_NAME:key中的值自减一
DECRBY KEY_NAME
append key_name value:字符串拼接,追加至末尾,如果不存在,为其赋值
hash(哈希)
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
常用命令
HSET key_name field value:为指定的key设定field和value
hmset key field value[field1,value1]
hget key field
hmget key field[field1]
hgetall key:返回hash表中所有字段和值
hkeys key:获取hash表所有字段
hlen key:获取hash表中的字段数量
-hdel key field [field1]:删除一个或多个hash表的字段
list(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
常用命令
lpush key value1 [value2]
rpush key value1 [value2]
lpushx key value:从左侧插入值,如果list不存在,则不操作
rpushx key value:从右侧插入值,如果list不存在,则不操作
llen key:获取列表长度
lindex key index:获取指定索引的元素
lrange key start stop:获取列表指定范围的元素
lpop key :从左侧移除第一个元素
prop key:移除列表最后一个元素
blpop key [key1] timeout:移除并获取列表第一个元素,如果列表没有元素会阻塞列表到等待超时或发现可弹出元素为止
brpop key [key1] timeout:移除并获取列表最后一个元素,如果列表没有元素会阻塞列表到等待超时或发现可弹出元素为止
ltrim key start stop :对列表进行修改,让列表只保留指定区间的元素,不在指定区间的元素就会被删除
lset key index value :指定索引的值
linsert key before|after world value:在列表元素前或则后插入元素
Set(集合)
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
常用命令
sadd key value1[value2]:向集合添加成员
scard key:返回集合成员数
smembers key:返回集合中所有成员
sismember key member:判断memeber元素是否是集合key成员的成员
srandmember key [count]:返回集合中一个或多个随机数
srem key member1 [member2]:移除集合中一个或多个成员
spop key:移除并返回集合中的一个随机元素
smove source destination member:将member元素从source集合移动到destination集合
sdiff key1 [key2]:返回所有集合的差集
sdiffstore destination key1[key2]:返回给定所有集合的差集并存储在destination中
zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
常用命令
ZADD key score1 memeber1
ZCARD key :获取集合中的元素数量
ZCOUNT key min max 计算在有序集合中指定区间分数的成员数
ZCOUNT key min max 计算在有序集合中指定区间分数的成员数
ZRANK key member:返回有序集合指定成员的索引
ZREVRANGE key start stop :返回有序集中指定区间内的成员,通过索引,分数从高到底
ZREM key member [member …] 移除有序集合中的一个或多个成员
ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员(第一名是0)(低到高排序)
ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员
Redis持久化
Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数 据恢复。
RDB
RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发
手动触发
手动触发分别对应save和bgsave命令
save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存 比较大的实例会造成长时间阻塞,线上环境不建议使用
bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子 进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短
自动触发
使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改 时,自动触发bgsave。
如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点,更多细节见6.3节介绍的复制原理。
执行debug reload命令重新加载Redis时,也会自动触发save操作。
默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则 自动执行bgsave。
bgsave是主流的触发RDB持久化方式
RDB优缺点
优点
RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据 快照。非常适用于备份,全量复制等场景。比如每6小时执行bgsave备份, 并把RDB文件拷贝到远程机器或者文件系统中(如hdfs),用于灾难恢复。
Redis加载RDB恢复数据远远快于AOF的方式。
缺点
RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运 行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式 的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。
针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解决。
AOF
AOF(append only file)持久化:以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用 是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
使用AOF
1.打开 redis.conf 文件,找到 APPEND ONLY MODE 对应内容,默认是关闭的,需要打开
appendonly yes
2.指定本地数据库文件名,默认值为 appendonly.aof
appendfilename “appendonly.aof”
3.指定更新日志条件
# appendfsync always
appendfsync everysec
# appendfsync no
always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
everysec:出厂默认推荐,每秒异步记录一次(默认值)
no:不同步
4.配置重写触发机制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
AOF优缺点
优点
AOF可以更好的保护数据不丢失。
AOF日志文件以append-only模式写入,写入性能比较高。
AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
适合做灾难性的误删除紧急恢复。
缺点
对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大,恢复速度慢。
AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的。
总结
1、不要仅仅使用RDB,因为那样会导致你丢失很多数据。
2、也不要仅仅使用AOF,因为那样有两个问题:
你通过AOF做冷备,没有RDB做冷备,恢复速度更快,
第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug。
3、综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择,
用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。
事务
可以一次执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞
事务常用命令
1.DISCARD:取消事务,放弃执行事务块内的所有命令
2.EXEC:执行所有事务块内的命令
3.MULTI:标记一个事务块的开始
4.UNWATCH:取消WATCH命令对所有key的监视
5.WATCH key [key…]:监视一个或多个key,如果在事务执行之前这个(些)key被其他命令所改动,那么事务被打断
WATCH
Watch指令,类似乐观锁,事务提交时,如果key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会执行
通过watch命令在事务执行之前监控了多个key,倘若在watch之后有任何key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败
事务的错误处理
1.如果队列中有命令输入错了,则整个队列都不会执行成功
2.如果队列中指令没有错,在执行过程中,指令执行失败,则只有当前指令失败,其它还是会成功
事务的三个阶段
1.开启事务
2.加入队列
3.执行事务
特性
1.单独的隔离操作:事务中的所有命令都会序列化,按顺序的执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
2.没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这个问题。
3.不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。
Redis消息发布订阅
发布订阅
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
常用命令
subscribe channel [channel…]:订阅一个或多个频道的信息
psubscribe pattern [pattern…]:订阅一个或多个符合规定模式的频道
publish channel message :将信息发送到指定频道
unsubscribe [channel[channel…]]:退订频道
punsubscribe [pattern[pattern…]]:退订所有给定模式的频道
Redis主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制的作用
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
一主二从
一主二从指有一个主节点(master/leader)和两个从节点(slave/follower)
配置
开启三个redis镜像,外网访问端口分别是79,80,81
端口为79
docker run -p 6379:6379 -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data --name myredis79 -d redis
端口为80
docker run -p 6380:6379 -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data --name myredis80 -d redis
端口为81
docker run -p 6381:6379 -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data --name myredis81 -d redis
创建完成
设置端口为79的为主节点(master/leader)
需要先看79端口的ip地址可以用docker命令查看
docker inspect 镜像ID
分别进入三个镜像
首先查看79端口的信息,用info replication查看当前79端口信息
info replication
默认显示79端口为主节点,没有从节点
80和81端口也是一样的
在将80和81端口设置为79端口的从节点,命令:
SLAVEOF IP地址 端口号
IP地址是刚才查看的79端口的ip地址:172.X.X.X
端口号是redis的外网查看端口号:6379
这样显示则显示连接成功,再去查看79端口信息
80端口和81端口
显示如下,则代表,一主二从配置成功
薪火相传
上一个slave可以是下一个slave的Master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。
配置
79和80端口不变
81端口连接80端口
80端口显示如下
显示自己还是从机,但自己算主机,79的从机,81的主机,这样减少了79的压力,但却添加了风险更大,如果80从机挂掉,则81也接受不到消息
反客为主
将从机升成主机
命令
SLAVEOF no one
配置
假如79主机挂了,则正常情况,80和81都不会有所行动,这时需要挑选一个主机出来,控制从机。
这时,80端口就是主机了,79端口就算回来也不再是它们的主机
哨兵模式
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
配置
79,80,81端口下, 自定义的/myredis目录下新建sentinel.conf文件(名字绝不能错),配置哨兵,填写内容
sentinel monitor ip地址 端口号 1
上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机
复制的缺点
复制延时
因为读写分离,所有的写操作在主机上,传到从机上需要时间,当系统繁忙或者,访问量大的时候,延时时间将会更长,从机的数量越多,延时越严重