前言
这里将持续整理一些 Redis 核心笔记
中文社区:redis.cn
1. 简介
单线程为什么这么快?
- 纯内存
- 非阻塞IO
- 避免线程切换和竞争消耗
单线程Redis注意事项
-
一次只运行一条命令
-
拒绝长(慢)命令,例如:keys、flushall、flushdb、slow lua script、mutil/exec、operate big value(collection)
-
Redis其实不是单线程,fysnc file descriptor进行持久化
特性
- 速度快
- 持久化
- 多钟数据结构
- 支持多种编程语言
- 功能丰富
- 简单
- 主从复制
- 高可用,分布式
2. 应用场景
缓存系统
排行版
计数器
社交网络
消息队列系统
实时系统
3. 数据类型
| 结构类型 | 结构存储的值 | 结构的读写能力 |
|---|---|---|
| STRING | 可以是字符串、整数或者浮点数 | 对整个字符串或者字符串的其中一部分执行操作 对整数和浮点数执行自增或自减操作 |
| LIST | 一个链表,链表上的每个节点都包含了一个字符串 | 从两端压入或者弹出元素 对单个或者多个元素 进行修剪,只保留一个范围内的元素 |
| SET | 包含字符串的无序收集器(unordered collection),并且被包含的每个字符串都是独一无二、各不相同的 | 添加、获取、移除单个元素 检查一个元素是否存在于集合中 计算交集、并集、差集 从集合里面随机获取元素 |
| HAST | 包含键值对的无序散列表 | 添加、获取、移除单个键值对 获取所有键值对 检查某个键是否存在 |
| ZSET | 字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定 | 添加、获取、删除元素 根据分值范围或者成员来获取元素 计算一个键的排名 |
STRING
设置语法
set key value [EX seconds] [PX ms] [nx|xx]
- key: 键名
- value: 键值
- ex seconds: 键秒级过期时间
- ex ms: 键毫秒及过期时间
- nx: 键不存在才能设置,setnx和nx选项作用一样,用于添加,分布式锁的实现
- xx: 键存在才能设置,setxx和xx选项作用一样,用于更新
常用命令
> set hello world
OK
> get hello
"world"
> del hello
(integer) 1
> get hello
(nil)
书中提到一个有趣的概念,批量操作mget可以提供效率节省时间
逐条 get/se t的时间消耗公式:
n次get/set时间 = n次网络时间 + n次命令时间
批量get/set的时间消耗公式: n次get/set时间 = 1次网络时间 + n次命令时间
合理的使用批量操作可以提高Redis性能,但是注意不要量太大,如果过量的话可能会导致Redis阻塞
时间复杂度
- set: O(1)
- get: O(1)
- del: O(k),k为键的个数
- mget: O(k),k为键的个数
- mset: O(k),k为键的个数
- append: O(1)
- str: O(1)
- getrange: O(n), n为字符串的长度
内部编码
- int: 8字节长整型
- embstr: 小于39字节值
- raw: 大于39字节的值
典型场景
- 缓存
- 计算器
- 分布式锁
场景
- 缓存
- 计算器
- 分布式锁
LIST
> rpush list-key item (integer) 1 > rpush list-key item2 (integer) 2 > rpush list-key item (integer) 3 > lrange list-key 0 -1 1) "item" 2) "item2" 3) "item" > lindex list-key 1 "item2" > lpop list-key "item" > lrange list-key 0 -1 1) "item2" 2) "item"
SET
> sadd set-key item (integer) 1 > sadd set-key item2 (integer) 1 > sadd set-key item3 (integer) 1 > sadd set-key item (integer) 0 > smembers set-key 1) "item" 2) "item2" 3) "item3" > sismember set-key item4 (integer) 0 > sismember set-key item (integer) 1 > srem set-key item2 (integer) 1 > srem set-key item2 (integer) 0 > smembers set-key 1) "item" 2) "item3"
HASH
创建哈希类型的键值
127.0.0.1:6379> hset user name LotusChing (integer) 1 127.0.0.1:6379> hset user age 21 (integer) 1 127.0.0.1:6379> hset user gender "Male" (integer) 1
HSET 不支持创建一次性创建多field
127.0.0.1:6379> hset user name "LotusChing" age 21 (error) ERR wrong number of arguments for 'hset' command
获取哈希键中的field值
127.0.0.1:6379> hget user name "LotusChing" 127.0.0.1:6379> hget user age "21" 127.0.0.1:6379> hget user gender "Male"
HGET 不支持一次获取多个field
获取哈希键中的fields
127.0.0.1:6379> hekys user 1) "name" 2) "age"
获取哈希键中的所有field的value
127.0.0.1:6379> hvals user 1) "LotusChing" 2) "21"
删除哈希键中某个field
127.0.0.1:6379> hdel user age (integer) 1 127.0.0.1:6379> hkeys user 1) "name"
统计哈希中field的个数
127.0.0.1:6379> hkeys user 1) "name" 2) "age" 3) "gender" 127.0.0.1:6379> hlen user (integer) 3
批量设置哈希键的field
127.0.0.1:6379> hmset user name "LotusChing" age 21 gender "Male" OK 127.0.0.1:6379> hkeys user 1) "name" 2) "age" 3) "gender" 127.0.0.1:6379> hvals user 1) "LotusChing" 2) "21" 3) "Male"
批量获取哈希键中field的value
127.0.0.1:6379> hmget user name age gender 1) "LotusChing" 2) "21" 3) "Male"
判断哈希键中field是否存在
127.0.0.1:6379> hexists user name (integer) 1 127.0.0.1:6379> hexists user hobbies (integer) 0
一次性获取哈希键中所有的fields和values
注意:尽量避免使用hgetall,因为如果哈希键field过多的话,可能会导致Redis阻塞,建议使用hmget获取所需哈希键中的field值,或者采用hscan
127.0.0.1:6379> hgetall user 1) "name" 2) "LotusChing" 3) "age" 4) "21" 5) "gender" 6) "Male"
ZSET
> zadd zset-key 728 member1 (integer) 1 > zadd zset-key 982 member0 (integer) 1 > zadd zset-key 982 member0 (integer) 0 > zrange zset-key 0 -1 withscores 1) "member1" 2) "728" 3) "member0" 4) "982" > zrangebyscore zset-key 0 800 withscores 1) "member1" 2) "728" > zrem zset-key member1 (integer) 1 > zrem zset-key member1 (integer) 0 > zrange zset-key 0 -1 withscores 1) "member0" 2) "982"
参考资料:
4. 通用命令
-
keys
-
dbsize
-
del
-
exists
-
expire key seconds
-
ttl
-
persist
-
type
过期时间
redis> SET cache_page "www.google.com" OK redis> EXPIRE cache_page 30 # 设置过期时间为 30 秒 (integer) 1 redis> TTL cache_page # 查看剩余生存时间 (integer) 23 redis> EXPIRE cache_page 30000 # 更新过期时间 (integer) 1 redis> TTL cache_page (integer) 29996
6. Redis持久化
Redis 持久化之RDB和AOF - ITDragon龙 - 博客园 https://www.cnblogs.com/itdragon/p/7906481.html
参考资料
- [ops_book/listlie-886829.md at master · LotusChing/ops_book](ops_book/listlie-886829.md at master · LotusChing/ops_book)
更新日志
- 2018/9/4 init1.0





