第一章 综述
第一节
1. 数据库的分类
关系型数据库 – 磁盘读写(IO操作)
非关系性数据库(NoSQl)–内存操作
non-relational、not only sql
2. 单线程&高并发
Redis 一般使用为单线程
多线程下:CPU根据时间片分批处理每个线程时间段命令
3. Redis使用
Redis定位是缓存,提高数据读写速度,减轻对数据库存储与访问压力
Redis不建议存储敏感数据,Redis缓存是临时存储容易丢失数据
4. 怎么学Redis
在线入门:http://try.redis.io/
中文资料网站:
http://www.redis.cn/
https://www.runoob.com/redis/redis-tutorial.html
第二节 Redis数据类型
a. 常用:String、hash、list、set、zset
不常用:
b. 命令格式
key 参数数据
set name value
eg: set name dafei
1. String 类型
1.1 常用命令
- incr key —— 给数字类型值 +1
- decr key —— 给数字类型值 -1
- setex key second value
eg:setex sex 5 man
设置value的缓存时间 - ttl key:查看value缓存时间
# eg:
172.0.0.1:6379> ttl sex
(integet) -2
- del key —— 删除指定key
- setnx key value —— 如果key不存在,则创建;如果存在,不做任何操作
1.2 应用场景
- 计数器:incr key 1,用户每访问一次将浏览次数 +1,最终将数据同步到数据库
- 共享session
2. Hash 类型
类似java中的map
2.1 命令
- hset key field value
- hget key field value
- hdel key field
- hincrby key field 1 —— 某个字段+1比较常用
- hlen key —— 查看key下filed的数量
- hkeys key —— 查看key下的filed都是什么
- hvals key —— 查看key下的filed的value都是什么
- hgetall key —— 查看key下的所有field和value
2.2 应用类型
- session缓存共享
方案一(String):【侧重查询,修改比较麻烦】
eg:“user”:“{‘name’:‘name1’,‘token’:‘tonken1’}”
方案二(Hash):【侧重修改,查询比较麻烦】
eg:user:{name:name1,token:token1}
3. List 类型
类似与Java中Map<string,List> map
3.1 常用命令
- rpush key value
- lrange key start stop
eg:lrange hobby 0 3;(全部)lrange hobby 0 -1 - lpop key —— 从左面取值,取值后list就没有了
- rpop key —— 从右面取值,取值后list就没有了
- llen key —— 查看list值的数量
3.2 应用场景
- 用户收藏文章列表
4. Sst 类型
Set集合是String类型的无序集合,是通过HashTable实现,对接会我们可以取交集、并集、差集
类似Java中:Map<String,Set>
4.1 常用命令
- sadd key value
- smember key – 查询key的value
- srem key members [] – 删除集合中元素
- spop key count 从结合中随机弹出count个元素
重要命令 - sdiff key1 key2 —— 返回key1中特有元素(差集)
- sinter key1 key2 —— 交集
- sunion key1 key2 —— 并集(有重复的去重)
4.1 应用场景
- 去重
- 抽奖
5. ZSst 类型(sorted set)
5.1 常用命令
- zadd key value1 field1 value2 field2
- zrange key 0 -1 正序返回field
- zrange key 0 -1 withscores 返回field和value
- zincrby key value field —— 将field的值+value
- zrevrange key 0 -1 倒着返回
- zrank key field —— 查看field正序排行
5.2 应用场景
- 排行榜
6. 类型总结
- 思考点
- 项目中是否需要使用缓存
- 使用缓存是否使用Redis
- 使用Redis如何设计key-value
- Value设计
既value类型选用:String Hash List Set ZSet
- 是否需要排序(ZSet)
- 缓存数据是单个还是多个
- 多个:允许重复List,不允许重复Set
- 单个:简单值String,对象值Hash
Redis中没有泛型,取值之后需要在程序中对值进行类型转换
- Key设计
- 唯一性:缓存数据主键作为key
- 可读性:普通单值;表名:主键名:主键值:列名;业务模块名:业务逻辑含义:其他:value类型
- 灵活性:一般key保证唯一时,可以使用主键;有的使用一个主键不能表达除全部意思可以使用联合主键。
- 时效性:Redis key一定要设置过期时间。
不设置过期时间的key为永久key,会一直占用内存,一般配合key过期策略使用;key的时效性设置需要根据业务场景设置。
第二章 高效使用
第一节 全局命令
1.
- keys pattern —— 查看所有key
Redis是单线程操作,keys * 命令在查询结果很多时,执行很慢 - exists key —— 判断key是否存在
- expire key seconds —— 给key 设置过期时间
- persist key ——取消过期时间
- select index——切换数据库
- move key db——从当前数据库将key移动到指定db库
- randomkey——随机返回一个key
- rename key newkey——将key改名
- echo message——打印message
- dbsize——查看keys个数
- info——查看redis数据库信息
- config get *——查看所有redis配置信息
- flushdb——清空当前数据库
- flushall——清空所有数据库
第二节 安全性
设置Redis密码
redis.conf中requirepass自定义密码
后续进入redis使用:redis-cli -a pwd
第三节 事务
- 事务从开始到执行经历:
- 开始事务
- 命令入队
- 执行事务
- 单个Redis命令是原子性的,但是Redis没有在事务上增加任何维持原子性的机制,所以Redis事务执行不是原子性的。
- Redis事务可以理解为一个大包批量执行脚本,但批量指令并非原子化的操作,中间某条指令失败不会影响前面和后面指令的执行,既,不会中断也不会回滚。
- MULTI 其实是创建了一个任务队列,将后序的指令放入队列中。EXEC是队列的出队指令。
总结
- Redis事务可以一次执行多个命令,并且带有以下三个重要保证:
- 批量操作再发送EXEC命令前被放入队列缓存
- 收到EXEC命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
- 在事务执行过程中,其他客户端提交的命令请求不会插入到事务执行命令序列
续
第四节 持久化机制
- 快照方式(RDB,Redis DataBase,4版本之前默认)
- 文件追加(AOP,Append Only File)
- 混合持久化(Redis4版本之后,默认)
一、RDB
- 触发机制
- 手动触发:
- 使用save命令
会阻塞当前Redis服务器,直到RDB过程完成,如果内存数据较多,会造成长时间阻塞,影响其他命令使用,不建议使用 - 使用bgsave命令
Redis进程执行fork指令创建子进程,由子进程实现RDB持久化,有需要时建议使用bgsave命令
- 使用save命令
- 自动触发:
- 使用save配置(格式:save m n;表示m秒内数据集存在n次修改时会自动出发bgsave命令)
- 优点
- RDB快照文件是一个紧凑的二进制文件,非常适用于备份,全量复制等场景。开发中可以按照每6小时执行一次bgsave备份,用于容灾备份。
- Redis加载RDB回复数据远远快于AOF方式
- 缺点
- RDB无法做到实时持久化/秒级持久化,每次bgsave时都需要fork子进程,频繁执行有时间成本
- RDB快照文件不同版本格式不同,容易引起兼容问题
二、AOF方式
- 策略
- appendfsync always:收到命令就立即写到磁盘,效率慢,但是能保证完全持久化
- appendfsync everysec:每秒写入磁盘一次,在性能和持久化方面做了很好折中
- appendfsync no:完全依赖os,一般同步周期是30秒
- 优点
- AOF方式数据安全性高,配置得当,最多损失1秒的数据
- 在不小心执行flushall命令,也可以通过AOF方式恢复(删除最后一条命令即可)
- AOF日志是一个增量日志文件,不会存在断电是出现损坏的问题。及时出现问题,redis-check-aof工具也可以轻松修复
- 当AOF变得太大,Redis能够在后台自动重写AOF
- 缺点
- 相同数据量来说,AOF文件体积通常大于RDB文件
- 数据持久性能上来说,AOF比RDB慢
三、RDB-AOF混合方式
写入时,当前数据用RDB方式存储,后序的操作命令以AOF方式存入文件
第五节 淘汰机制
一、内存淘汰机制
也叫key内卷机制
- LRU (Least Frequently Used):最近最少使用,仅和时间有关
- LFU (Least Frequency Used ):一段时间内,最不经常使用,使用次数最少的淘汰。这个与频次与时间有关
- TTL,让设置过期时间的,快过期的先淘汰
- 随机淘汰
二、 Redis淘汰策略
Redis通过设置 maxmemory-policy
8种
- volatile-lru:找出已经设置过期时间的数据集,将最近最少使用(被访问到)的数据干掉
- volatile-ttl:找出已经设置过期时间的数据集,将即将过期的数据干掉
- volatile-random:找出已经设置过期时间的数据集,随机干掉数据
- volatile-lfu:找出已经设置过期时间的数据集,将一段时间内,使用次数最少的数据干掉
- allkeys-lru:全体数据中最少使用(被访问)的干掉
- allkeys-lfu:全体数据使用次数最少的干掉
- allkeys-random:全体数据中随机干掉
- no-enviction:什么都不做,报错,提示内存不足。(可以保证数据不丢失)
默认使用:no-enviction
三、过期key处理
- 惰性删除:访问key时才判断是否过期。过期的干掉。优:对CPU友好。缺:内存浪费
- 定时删除:设置键的过期时间同时,创建一个定时器,到达过期时间,立即执行对key的删除。缺:对CPU不友好,额外让出CPU维护定时器
- 定期删除:隔一段时间,对数据进行一次检查,删除过期的key;要删除多少过期key,检查多少数据,由算法决定
Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用两种删除策略,可以很好地在合理使用CPU和避免浪费内存之间取得平衡。
Java操作Redis
jedis
Lettuce