redis
常用命令
- 启动redis:redis-service
- 打开redis客户端:redis-cli
- 关闭redis:在客户端输入shutdown
- DBSIZE:数据库的数量
- select:选择数据库
**================================================**
-
keys *:查询所有的键
-
type key:获取对应key的类型
-
del key:删除指定的key value
-
exists key:判断key是否存在
-
move key int:将key移动到数据库下标为int的库中(redis数据库都是以下标命名0,1,2…)
-
ttl(time to live) key :key 存活时间(-1:永不过期,-2:已经过期)
-
expire key 秒钟:给key设置过期时间
持久化
五大数据类型
- String
- Hash
- List
- Set
- Zset(有序集合)
String类型
String类型是(key,value);
String类型是二进制安全的,可以包含任何数据,如图片或者序列化对象;
String类型中value最大容量为512m;
- set key value 设置值
- get key 得到值
- del key 获取值
- append key 字符串:在key后追加字符串
- STRLEN key:获取key的value的长度
- INCRBY key int:将key的值+int(值必须为数字,int可以不写 默认为1)
- DECRBY key int:-int
- getrange key start end:获取指定范围内的值 ,包含头尾,类似 substring(),end为-1时,end为末尾
- setrange key start :设置从start位置开始覆盖为xxx,xxx后面的值不变
- setex key seconds value:在设置key时设置key存活seconds秒,值为value
- setnx key value:当key不存在时插入key,存在时不插入也不覆盖
- mset k1 v1 k2 v2…:一次设置多个键值(中间用空格分隔)
- mget k1 k2 k3…:一次获取多个值(中间用空格分隔)
- msetnx k1 v1 k2 v2…:当key不存在时一次设置多个值,当其中有已经存在的key时,设置全部失效
Hash 类型
Redis哈希是一个键值对集合,key-v模式不变,但是v是一个或者多个键值对组成的集合
- 存储:
- hset key field value(field类似java对象中的属性)
- hmset key f1 v1 f2 v2…:设置多个键值对
- 获取:
- hget key field:获取指定field的对应值
- hgetall key:获取所有的field和value
- hmget key f1 f2 f3…:获取多个键对应的值
- hlen key:获取map的长度
- hkeys key:获取map集合中所有的key
- hvals key:获取map中所有的 value
- 删除:hdel key field
- 设置:
- hincrby key field int:将field增加int,field必须为数值类型
- hincrbyfloat key field float:将field增加float,field必须为数值型
- hsetnx key field value:如果集合中没有field属性,则添加键值对,否则不添加
- 判断:hexist key field;判断map中有没有field属性(有是1,没是0)
List 类型
Redis列表是简单的字符串列表,按照插入顺序排列,底层是链表;
- 添加:
- lpush key v1 v2 v3 从左边加入
- rpush key v1 v2 v3 从右边加入
- 获取:
- lrange key start end 获取范围内的值(end为-1时表示end为末尾)
- llen:返回list的长度
- 删除:
- lpop key:删除列表左边的元素,并将元素返回
- rpop key:删除列表右边的元素,并返回
- lindex:按照索引下标获取元素(从上到下)
- lrem key n value:删除n个value
- rpoplpush 列表1 列表2:列表1 rpop 一个值,列表2 lpush一个值,即列表1的从右边移除一个放在列表2的左边
- 设置值 :
- lset key index value
- ltrim key start end:将key重新设置为start-end区间的值,包含start包含end
- 插入值:
- linsert key before/after v1 v2:v1前/后插入v2
Set 类型
- 添加:
- sadd key v1 v2 v3:向set集合添加v1 v2 v3
- smove key1 key2 key1.value1:将key1中的value1 移动到key2;
- 获取:
- smembers key:获取key中的值
- scard key:获取集合里元素的个数
- srandmember key count:随机取出count个值(不删除)
- spop key count:随机出栈count个值(删除)
- 判断
- sismember key value:判断key中是否存在value值,返回0或1
- 删除
- srem key value:删除集合中的元素
- spop key:随机出栈一个值
- 数学集合操作
- 差集 sdiff key1 key2 :获取key1中有 key2中没有的值
- 交集 sinter key1 key2:获取key1和key2都包含的值
- 并集 sunion key1 key2:获取key2 和key2的并集
Zset
有序set,在set基础上加入了score值
- 添加
- zadd key sc1 v1 sc2 v2…
- 获取
- zrange key start end 获取start-end的score
- zrange key start end withscores 获取start-end的score和value
- zrangebyscore key score1 score2获取score1到score2之间的value(含头尾)
- zrevrangebyscore key score1 score2 逆序获取score1到score2之间的value(含头尾)
- zrangebyscore key score1 (score2 ( 括号表示不含,,含头不含尾 score1<=x<score2)
- zrangebyscore key score1 score2 limit start count (start表示开始位置,count表示数量,即表示结果集中start开始count个,类似分页中的limit)
- zcard key:统计个数
- zcount key min max:获取score在min和max之间的数量
- zscore key value:获取value的score
- zrevrank key value,逆序获得score值
- 删除
- zrem key value:删除值value
- zrem key value:删除值value
缓存过期策略
常见配置
持久化存储
RDB(Redis DataBase)
SnapShotting快照:把当前的数据像快照一样存储到硬盘,redis会启动fork,让fork去完成持久化动作,这样可以使redis线程依然可以操作数据库,完成持久化和数据库操作互不干扰,但是redis在快照之后的数据操作不会存储到数据库,可能会丢失一部分数据。
RDB触发方式
save
执行save命令,可以触发持久化,但是持久化期间redis不能进行其他操作
bgsave
执行bgsave命令,异步触发持久化,数据库可以进行其他操作
默认触发机制
save 秒钟 读写操作次数
默认配置:
1分钟读写1万次
5分钟读写10次
15分钟读写1次
禁用:
save “” 或者不设置任何save配置
Stop-writes-on-bgsave-error
表示如果持久化出错,停止写入数据库;
默认 Stop-writes-on-bgsave-error yes;
如果改为no,可能造成数据不一致
rdbcompression
rdb文件会随着redis数据库的增加而不断增加,这个配置可以对rdb文件使用LZF算法进行压缩,以节省磁盘资源。但是会稍微增加cpu负担,但是付出这点负担换取压缩带来的空间完全是值得的
rdbchecksum
此设置用于对快照使用CRC64算法进行校验,会增加大约10%的性能负担,建议使用;
AOF(Append Only File)
AOF 和 RDB之间的选择
同时开启两种保存方式
性能建议:
RDB作为后备用途,建议只持久化到slave上,15分钟持久化一次足矣,只保留save 900 1这条持久化配置就可
如果启动aof,那么可以最大限度的保障数据的一致性,最坏情况下顶多丢失2秒的数据,但是rewrite所带来的阻塞机会是不可避免的,在硬盘容量许可的情况下应该尽量减少rewrite,aof重写的初始大小64m太小,会导致前期频繁的rewrite,建议初始大小5g以上
如果不启动aof ,仅靠Master-Slave Replication 实现高可用性也可以,但是如果Master和Slave同时倒掉,会丢失10几分钟的数据,重新启动时也要比较两个Master/Slave中的数据一致性
事务
redis事务:redis是部分支持事务,redis并不像mysql那样严格且强制性,再有些情况下,某行命令中含有错误,那么不会导致整个事务全部失败,而仅仅是出错的命令行失败,其他的语句照样可以执行。后面会有例子。
特性
- 不保证原子性
- 没有隔离级别的概念,因为redis事务中的命令在执行exec之前都不会实际的执行,所以不存在隔离级别
事务执行过程
- 1先用multi 开启命令,如果可以开启事务,返回ok
- 2添加语句队列如:set k1 v1;set k2 v2;…
- 3使用exec执行事务,这时如果没有任何出错,语句队列queued中的redis操作将会被执行
- discard命令用于放弃事务
关于redis部分事务的理解
MULTI
INCR K1 //注意:此时k1对应的value是字符型 不能执行+1操作 但是符合redis语法
set k1 v1
set k2 v2
exec
该事务除了第一条错误语句执行之外其他的均执行成功
MULTI
setget k1 v1 //注意 此时该语句不能通过redis的语法验证
ERR .......//上面语句导致redis会显示报错
set k1 v1
set k2 v2
set k3 v3
exec
该事务所有的命令都不能执行
watch监控
watch监控用于避免多个事务同时操作一个元素时产生的问题,当被watch监控期间,如果该元素被更改,那么下面的事务将不会执行。再开启事务时,如果有并发的变量,应当采用watch进行监控。
取消监控用unwatch
如果不采用watch将可能造成并发问题:
事务1 | 事务2 | 事务3 |
---|---|---|
开启 | 开启 | 开启 |
存入100元 | ||
取出100元 | 取出100元 | |
关闭 | 关闭 | 关闭 |
因为事务3没有使用watch 导致事务3不能正确监听到事务2已经取出了100元,所以事务三偷走了100元,如果开启了watch,那么事务3将不会执行
事务正确的使用步骤
set money 100
watch 100
MULTI
set money 0
exec
Redis复制Master/Slave
介绍:也就是所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,master可以写,slave以读为主。
- 当建立了主从同步时,从机会自动读取主机所有的数据到自己的数据库中,即使在建立联系之前的数据,这样设计是很有必要的
- 从机默认只能读取数据而不能更改数据
- 主机down掉后,从机将会等待主机的连接,并且这段期间,对数据库无法进行任何操做,因为主机down了,从机不能写数据
复制原理:
Slave成功连接到master后,会发送一个sync命令,master接收命令后启动存盘进程,同时收集所有修改数据库的命令,在后台进程执行完毕后,master发送整个文件给slaver,完成一次全量复制,每次连接master,都会进行一次全量复制,后面如果master被修改,那么master会把修改的命令发送给slave,完成同步,这种同步成为增量复制
主要作用:读写分离 容灾恢复
常用命令:info replication
用于查看当前客户端所处角色,以及slave的状态
步骤:
- 配从不配主
- 从库配置:slaveof 主库ip 主库端口
- 每次与master断开都需要重新配置,写入redis.conf文件可以实现自动配置
- 主机,从机必须开放6379端口,防火墙要开放端口
- 主机,从机的配置文件中bind属性设为0.0.0.0表示任何机器都可以连接
- 必须启动时加载配置文件,不然配置文件不能生效
哨兵模式
作用:当采用主从复制模式时,如果主机down机,那么自动在从机中选出一个作为主机,以避免主机down机导致redis全部瘫痪
使用步骤:
- 在myredis目录下,新建sentinel.conf文件
- 配置哨兵
- sentinel monitor <主机数据库名字> <主机ip> <主机端口> 1