菜鸟教程:https://www.runoob.com/redis/redis-tutorial.html
Redis 为什么这么快?
- 采用了多路复用 IO
- 数据结构简单,操作节省时间
- 内存操作
- 单线程:
- 没有上下文切换消耗
- 没有竞争和锁
Redis 为什么采用单线程?
五种基本数据类型:
- String:整数、浮点数、字符串。最大容量 512M
- long
- long double
- SDS
- Set:集合
- intset 或者 hashtable
- Zset:有序集合
- ziplist 或者 skiplist
- Hash:散列表
- ziplist 或者 hashtable
- List:列表
- ziplist 或者 linkedlist
数据结构:
- SDS:Simple dynamic string
- linkedlist:链表
- skiplist:跳跃表
- intset:整数集合
- ziplist:压缩列表
- hashtable:哈希表
过期策略
定期删除 + 惰性删除:
定时删除:设置 key 过期时间的同时,创建定时器
- 定期删除:每 100ms 检查和删除随机抽取的 key
- 惰性删除:获取 key 的时候检查过期时间,再删除
问题:如果定期删除和没有请求某个 key,会导致大量过期的 key 占用内存。
所以需要有内存淘汰策略。
内存淘汰策略:
- volatile-lru:以设置过期时间的数据集中,选择最近最少使用的数据,淘汰
- volatile-ttl:以设置过期时间的数据集中,选择快要到期的数据,淘汰
- volatile-random:以设置过期时间的数据集中,随机选择数据,淘汰
- allkeys-lru:从所有数据集中,选择最近最少使用的数据,淘汰
- allkeys-random:从所有数据集中,随机选择数据,淘汰
- noeviction:禁止淘汰数据。满了之后,后续写入操作会报错
least recently used:最近最少使用
配置:redis.conf -> maxmemory-policy volatile-lru
持久化:
- RDB:(Redis Database) 默认
- 全量备份
- 慢
- 按照一定的时间周期策略,保存到快照文件 dump.rdb。
- 配置文件 save 属性设置周期
- AOF: (Append Only File 追加只读文件)
- 增量追加到 AOF 文件的末尾
- 需要设置同步选项:
- always:会严重降低服务器的性能
- everysec:每秒写入一次。影响不大
- no:不写入。并不会提升性能,而且有丢失数据的风险
- 会将每一个写命令通过 write 函数追加到文件末尾,类似于 MySQL 的 binlog
- 当两种备份都开启,优先选择 AOF 进行数据恢复
事务:
MULTI、EXEC、DISCARD、WATCH
Redis 会将一个事务的所有命令序列化,然后按顺序执行
- 不支持事务的回滚,如果失败了会继续执行余下命令
- 如果命令的语法错误,所有命令都不会被执行
- 如果命令执行错误,那么正确的命令会被执行
流程:
- MULTI 开启事务,返回 OK。后续发送的命令不会马上执行,而是被放入一个队列
- EXEC 开始执行事务中的命令。如果被打断,返回空值 nil
- 调用 DISCARD 可以清空事务队列,放弃事务
- WATCH 可以监控一个或多个 key,一个被修改或删除,之后的事务就不会执行。监控一直持续到 EXEC 命令
操作:
SET key1 value1
DEL key1
# 正则获取key
keys pattern
# 判断 key1 是否存在
EXIST key1
# 设置过期时间,单位秒
EXPIRE key1 60
# 设置过期时间,单位时间戳
EXPIREAT key1 timestamp
# 移出过期时间
PERSIST key1
# 返回过期时间,s
TTL key1
# 类型
TYPE key1
String:
GET/SET
# 设置key1的值和过期时间
SETEX key1 sec value
# key1 不存在才设置
SETNX key1 valu1
# 返回对应值的字符串长度
STRLEN key1
# 自增自减
INCR key1
DECR key1
set key value [EX seconds] [PX milliseconds] [NX|XX]
# EX seconds:设置失效时长,单位秒
# PX milliseconds:设置失效时长,单位毫秒
# NX:key不存在时设置value,成功返回OK,失败返回(nil)
# XX:key存在时设置value,成功返回OK,失败返回(nil)
List:
# 添加元素到 list1
LPUSH list1 e1
Hash:map
获取 map1 中 name 字段的值
HGET map1 name
获取 map1 中所有键值对
HGETALL map1
删除 map1 中指定字段
HDEL map1 name addr
———————————————————————-
给 map1 设置多个键值对,返回成功的数量
HSET map1 name demojie addr guangzhou
同上,返回成功或失败.覆盖原始值也算成功
HMSET map1 name demojie addr guangzhou
———————————————————————-
设置 map1 中的 name 为 demojie,如果不存在的话
HSETNX map1 name demojie
获取 map1 中所有的值
HVALS map1
```
TODO
BloomFilter