The Little Redis Book
the little redis book: https://github.com/JasonLai256/the-little-redis-book/blob/master/cn/redis.md
入门
关于持久化和数据查询的相关技术 -> 关系型数据库再也不是放之四海皆准 -> 围绕数据的解决方案不可能再只有唯一一种
redis: 容易学习; 在处理一组特定的问题集的同时能保持相当的通用性 -> 什么是可行的,什么是不应该由Redis来处理的
入门: 实践 -> 学习
源文件来安装: 二进制可执行文件会被放置在src目录里
驱动Redis: 客户端推荐页面
./redis-server: 如果没有指定redis.conf文件, Redis将会采用内置的默认设置./redis-cli: info -> 查看服务器的状态redis-benchmark: >=1w - >=10w/s
第1章 - 基础知识
什么是redis? -> more than in-memory persistent key-value store(内存内可持久化存储器)
5种数据结构 -> 工作原理 -> 关联方法 -> 构建模型
关系型数据库 -> table -> one-size-fits-all vs 针对特定类型的问题使用特定的数据结构(标量、列表、散列和集合)
sql: 致力于让数据库的数据往返次数减至最小
db: redis 也有; 典型应用 -> 一个程序对应一个db, 和其它程序的数据保持独立; select 1 -> 切换db, 默认为0
key: 关键字, 用来标识数据块; 标量; users:leto -> 使用分隔符来组织关键字是很常见的方法
value: 关键字的实际值; everything -> 整数 + 字符串 + 序列化对象(json/xml/其它格式)
command: 操作 key+value
query: 关键字就是一切 -> 不允许你通过值来进行查询
Memory and Persistence(3种方式):
- 默认: 根据已变更的关键字数量 -> 在磁盘里创建数据库的 snapshot; 如 >=1000/60s, <=9/15m
- 附加模式: 一个关键字变更 -> 一个单一附加(append-only)的文件会在磁盘里进行更新
- 将持久化任务减荷到一个从属数据库里
IO-bound vs CPU-bound: 根据双方瓶颈和业务需求决定需要使用 空间->时间 还是 时间->空间(压缩算法, gc算法)
Putting It Together(整体来看): 查询的限制 + 数据结构 + Redis在存储器内存储数据的方法 -> 速度; 并不适用于所有的应用场景
第2章 - 数据结构
**Redis的网站
不同的数据结构 -> 不同的问题 -> 很多问题 redis 是理想选择 -> 很多时候只用一部分就可以解决问题
flushdb: 数据库里的所有值清除掉, flushall 清除所有 db
strings
set users:leto "{name: leto, planet: dune, likes: [spice]}" # set <key> <val>get users:leto # get <key>strlen <key>getrange <key> <start> <end>append <key> <value> # 不存在则创建# 支持并发incr/decr <key>incrby/decrby <key> <num># bitmaps: http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/setbit/getbit # 今天我们有多少个独立用户访问 -> 2个命令/1.28亿/50ms/16mbhash(散列)
提供了一个额外的 filed(域): 存储一个用户 vs 序列化对象 -> set/get/del 数据片段 vs set/get 全部
hset users:goku powerlevel 9000 # hset <field> <key> <val>hget users:goku powerlevel # hget <field> <key>hmset users:goku race saiyan age 737hmget users:goku race powerlevelhgetall users:gokuhkeys users:gokuhdel users:goku agelist(列表)
one key -> vals(一组值)
维护了 val 的顺序 -> 基于索引的高效操作
操作: 添加 获取第一个 获取最后一个 用给定的索引来处理
应用: 跟踪新用户 -> newusers list; 跟踪用户排队活动
lpush newusers gokultrim newusers 0 50 # ltrim <key> <start> <stop>, 只留下范围内的值, 其他删除set(集合)
存储只能唯一存在的值
基于集合的操作, 如 并集
对值没有排序, 但其提供了高效的基于值的操作
典型应用: 好友名单; 集合操作; 需要对值的属性进行标记和跟踪处理
sadd friends:leto ghanima paul chani jessica # 添加好友sadd friends:duncan paul jessica aliasismember friends:leto jessica # 是否有此好友sismember friends:leto vladimirsinter friends:leto friends:duncan # 是否有共同好友sinterstore friends:leto_duncan friends:leto friends:duncan # 存储共同好友到 new setsorted set(分类集合)
set + score(标记) -> sort(排序) + rank(秩)
zadd friends:duncan 70 ghanima 95 paul 95 chani 75 jessica 1 vladimirzcount friends:duncan 90 100 # >=90 的人数zrevrank friends:duncan chani # 获取 降序 rankzrank <key> <member> # 升序第3章 - 使用数据结构
Big O Notation: 许多Redis命令都具有O(1)的时间复杂度; O(1) -> O(log(N)) -> O(N); N 不一定是记录总数; 发现一些操作具有O(N)的时间复杂度时 -> 可能可以找到更为好的方法去处理
Pseudo Multi Key Queries(仿多关键字查询): 例如要通过 id/emali 来查询用户, 使用使用 hash 来设置 id->emali 的映射
References and Indexes(引用和索引): 值与值之间索引和引用, 必须手动更新, 比如 朋友圈问题, 如果一个用户 改名/删除账号, 那么朋友圈里面所有人的状态都需要修改
Round Trips and Pipelining(数据交互和流水线): 有的命令支持多个参数; 流水线功能 -> 发送多个请求, 而不需要等待Redis响应
Transactions(事务): Redis实际上是单线程运行 -> 每一个命令保证原子性; 如果开启多进程 redis, 仍然会有并发问题
Keys Anti-Pattern(关键字反模式): 能会尝试去使用keys命令 -> 使用 hash 来实现, 例如 bug 追踪时对 删除/更新 bug
# 事务multihincrby groups:1percent balance -9000000000hincrby groups:99percent balance 9000000000exec小结: 理解基本的数据结构 -> 洞察力 -> power 实际项目
第4章 超越数据结构
sort: 列表、集合或者分类集合里对值进行排序(分类集合按照 rank 来); 包含 store 能力, 可以和 expire 结合使用
# expireexpire pages:about 30 # 秒expireat pages:about 1356933600 # 时间戳ttl pages:about # 查看过期时间persist pages:about # 删除过期时间# Publication and Subscriptions(订阅和发布)blpop/brpop blpush/brpush # hash 中的命令; 阻塞; 可以用来实现一个简单的队列subscribe warnings # 订阅频道, 可订阅多个publish warnings "it's over 9000!" # 发布消息# Monitor and Slow Log(监控和慢查询日志)monitorconfig set slowlog-log-slower-than 0slowlogslowlog getslowlog get 10# sortrpush users:leto:guesses 5 9 10 2 4 10 19 2sort users:leto:guessessadd friends:ghanima leto paul chani jessica alia duncansort friends:ghanima limit 0 3 desc alpha# 基于 bug 严重级别的排序sadd watch:leto 12339 1382 338 9338set severity:12339 3set severity:1382 2set severity:338 5set severity:9338 4sort watch:leto by severity:* desc# 大数据量双维度排序hset bug:12339 severity 3hset bug:12339 priority 1hset bug:12339 details "{id: 12339, ....}"hset bug:1382 severity 2hset bug:1382 priority 2hset bug:1382 details "{id: 1382, ....}"hset bug:338 severity 5hset bug:338 priority 3hset bug:338 details "{id: 338, ....}"hset bug:9338 severity 4hset bug:9338 priority 2hset bug:9338 details "{id: 9338, ....}"sort watch:leto by bug:*->priority get bug:*->detailssort watch:leto by bug:*->priority get bug:*->details store watch_by_priority:leto小结: 可能不会用到, 但是多知道一点总是好的
第5章 - 管理
config: redis.conf -> well-documented, 一般不需要修改; config 来 get/set 配置
auth: 配置 requirepass 开启密码验证, auth password 通过验证; 重命名一些重要命令为混乱的字符串 -> 提高安全性; 重命名为空 -> 禁用
size limit: 每个实例 -> >=10^8
Replication(复制): 配置 slaveof -> master-slave; 没有提供自动故障恢复
backup(备份): Redis会把快照存储为一个名为dump.rdb的文件
Scaling and Redis Cluster(缩放/集群)
小结: Redis已经可以应用于实际生产中, 但是一些工具还是不够成熟, 尤其是一些安全性和可用性相关的工具
总结
something redis is not a good choice, something redis is just ok
but redis is so easy