一站式学习Redis 从入门到高可用分布式实践
# 一站式学习Redis 从入门到高可用分布式实践
> https://coding.imooc.com/class/151.html
系统学习Redis必备,企业级Redis开发运维经验
## 相关推荐
-–
# 第一章 Redis初识
## 1.1 导学
> 单机最高10万
- 高性能的Key-Value服务器
- 多种数据结构
- 丰富的功能
- 高可用的分布式支持
### 目录
- Redis 初识
- API 的理解和使用
- Redis 客户端的使用
- 瑞士军刀 Redis
- Redis 持久化的取舍和选择
- Redis 复制的原理和优化
- Redis Sentinel
- Redis Cluster
### 适合人群
- Redis 初学者
- Redis 进阶者
- 希望了解 Redis 企业级开发运维技巧
### 技术储备
- 了解 Linux 命令的基本使用
- 了解常用的数据结构
- 了解一门编程语言
### 授课思路
- 开发运维结合
- 原理接入
- 实战案例分析
### 课程目标
- 全面了解 Redis 单机的相关功能
- 全面了解 Redis 高可用和分布式方案
- 理解企业级 Redis 的开发运维
## 1.2 Redis 初识
+ Redis 的前世今生
- 作者:Salvatore Sanfilippo(antirez)
- 现已加入 redislabs (redis云服务)
+ Redis 是什么
- 开源(可定制化)
- 基于键值的存储服务系统
- 多种数据结构
- 高性能、功能丰富
+ Redis 的特性回顾
- Redis 的特性
- 速度快
- 10w OPS(每秒实现10w读写)
- 数据存在哪?内存
- 什么语言写的?C语言(50000 line)
- 线程模型? 单线程
-
- 持久化
- 断电不丢数据
- Redis 所有数据包吃在内存中,对数据的更新将异步地保存到磁盘上。
- 多种数据结构
-
- 多种数据结构-续(新版本):
- BitMaps:位图(很小内存高效存储)
- HyperLogLog:超小内存唯一值计数
- 缺点:计数有误差
- GEO:地理信息定位(>3.2版本)
- 支持多种编辑语言
-
- 功能丰富
- 发布订阅(消息队列)
- Lua 脚本(自定义命令)
- 事务
- pipeline(指的是管道技术,指的是客户端允许将多个请求依次发给服务器,过程中而不需要等待请求的回复,在最后再一并读取结果即可。)
- 简单
- 23000 lines of code(23000行代码)
- 不依赖外部库(like libevent)
- 单线程
- 主从复制
- 高可用、分布式
- 高可用 Redis-Sentine(v2.8)支持高可用
- 分布式 Redis-Cluster(v3.0)支持分布式
+ Redis 典型使用场景
- 缓存系统
- 对相关数据进行缓存
- 计数器
> redis实现计数器
- 社交产品业务里有很多统计计数的功能,比如:
- 用户: 总点赞数,关注数,粉丝数
- 帖子: 点赞数,评论数,热度
- 消息: 已读,未读,红点消息数
- 话题: 阅读数,帖子数,收藏数
- 文章的点赞数、页面的浏览数、网站的访客数、视频的播放数等
- 消息队列系统
- 排行榜
> Redis实现排行榜功能(实战)
- 游戏排行榜
- 社交网络
> 社交网络和Redis是天然吻合的;社交系统很多都可以使用 Redis 实现
- 粉丝数、关注数、最新时间轴列表
- 实时系统
- 垃圾邮件处理、消息队列缓冲系统
+ Redis 单机安装
- Redis 安装
- 可执行文件说明
- redis-server > Redis 服务器
- redis-cli > Redis 命令行客户端
- redis-benchmark > Redis 性能测试工具
- 续:
- redis-check-aof > AOF 文件修复
- redis-check-dump > RDB 文件检查工具
- redis-sentinel > Sentinel服务器(2.8以后)
- 三种启动方法
- 最简启动
- redis-server
- redis 服务查看:ps -ef | grep redis
- redis 端口查看:netstat -antpl | grep redis
- redis 连接查看:redis-cli -h ip -p port ping
- 动态参数启动
- 自定义启动端口:redis-server --port 6380
- 配置文件启动
- 配置文件启动:redis-server configPath
- 三种启动方式比较
- 生成环境选择配置启动
- 单机多实例配置文件可以用端口区分开
- 简单的客户端连接
-
-
-
- redis 常用配置
- daemonize > 是否是守护进程(no|yes)
- port > Redis 对外端口号
- logfile > Redis 系统日志
- dir > Redis 工作目录
- 端口号:6379 ?
-
- 其他配置:
- RDB config
- AOF config
- slow Log config
- maxMemory
- …
# 第二章 API的理解和使用
## 课程目录
### Redis API 的使用和理解
+ 通用命令
- 通用命令
- keys > 计算 Redis 库的所有的键
- keys *
遍历所有的key
- keys [pattern]
遍历所有key
> pattern 可以当做通配符
-
- keys 命令一般不在生产环境使用
- keys *
怎么使用
- 热备从节点
- scan
> Redis中的Scan命令的使用
> - Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式。
> - 一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行的,keys是以遍历的方式实现的复杂度是 O(n),Redis库中的key越多,查找实现代价越大,产生的阻塞时间越长。
> - 二是scan命令,以非阻塞的方式实现key值的查找,绝大多数情况下是可以替代keys命令的,可选性更强
- dbsize > 计算库的总数
-
- exists key > 判断一个 key 是否存在
-
- del key [key …] > 删除多个 key
-
- expire key seconds > 设置 key 过期时间
-
-
-
- type key > 设置 key 类型
-
- 时间复杂度
-
- 数据结构和内部结构编码
-
-
- 单线程架构
- Redis 单线程,
- 一瞬间只执行一条命令(串行结果),不会执行多条。
-
- 单线程为什么这么快?
- 纯内存
- 非阻塞IO
- 避免线程切换和竞态消耗
- 单线程需要注意什么?
- 一次只运行一条命令
- 拒绝长(慢)命令(数据过多时响应过久)
> keys,flushall,flushdb,slow lua script,mutil/exec,operate big value(collection)
- 其实不是单线程(执行以下操作时,会有独立的线程操作)
- fusnc file descriptor
- close file descriptor
+ 字符串类型
- 结构和命令
- 字符串键值结构
- 字符串值最大512MB,建议100kb左右。
-
- 场景
- 缓存
- 计数器
- 分布式锁
- 等等
- 命令
- get,set,del
-
-
- incr,decr,incrby,decrby
-
-
- 快速实战
- 实现如下功能:
- 1. 记录网站每个用户个人主页的访问量?
- incr userid:pageview
(单线程:无竞争)每个命令独立执行,不会记错数。
- 2. 缓存视频的基本信息(数据源在MySQL中)伪代码。
-
-
- 3. 分布式ID生成器。
> 每次获取到的ID自增,三个应用并发获取。
-
- incr id
(原子操作)
- set,setnx,set xx
-
-
- mget,mset
-
-
-
-
- 内部编码
- 查漏补缺
- getset,append,strlen
-
-
- incrbyfloat,getrange,setrange
-
-
- 字符串总结
-
+ 哈希类型
- 结构
-
-
- 特点
-
- 重要API
- hget,hset,hdel
-
-
- hexists,hlen
-
-
- hmget,hmset
-
-
- hgetall,hvals,hkeys
-
-
- hash vs string
-
- 以 用户更新用户属性?三种方案:
- 1.
- 2.
- 3.
- 三种方案比较:
-
- 查漏补缺
- hsetnx,hincrby,hincrbyfloat
-
- 实战功能:
- 1. 记录网站每个用户个人主页的访问量?
- hincrby user:1:info pageview count
- 2. 缓存视频的基本信息(数据源在MySQL中)伪代码
-
- 哈希总结
-
+ 列表类型
- 列表结构
- 有序列表
- 可以左插入、弹出和右插入、弹出。
- 计算长度
- 删除指定一个元素
- 获取列表的一个子列表
- 根据索引获取列表的指定元素
- 特点
- 重要API
- 都以 L 开头,先以增删改插为例:
- 增:
- rpush 从右端插入值
- lpush 从左端插入值
- linsert 指定的值前/后插入newValue
- lpop 从左侧弹出一个item
-
-
- rpop 从右侧弹出一个item
-
-
- 删:
- lrem 根据count值,从列表中删除所有value相等的项
-
-
-
- ltrim 按照索引范围修剪列表
-
-
-
- 查:
- lrange 获取指定索引范围所有item
- 获取索引0~2的数据
- 获取索引1~-1的数据
- lindex 获取指定索引的item
-
-
- llen 获取列表长度
- 改:
- lset 设置列表指定索引的值为newValue
-
-
- 实战
-
-
- 查漏补缺
- blpop lpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞
- brpop rpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞
- 列表总结 TIPS
\1. 栈:LRUSH + LPOP = Stack
\2. 队列:LPUSH + RPOP = Queue
\3. 控制一个有固定数量的队列(防止无限放大),控制列表大小:LPUSH + LTRIM = Capped Collection
\4. 消息队列:LPUSH + BRPOP = Message Queue
+ 集合类型
- 集合结构
-
-
-
-
-
- 特点
- 命令
> 以 s 开头
- sadd,srem
- sadd 向集合key添加元素(如果元素已存在则添加失败)
- srem 将集合key中的元素移除掉
- scard,sismember,srandmember,spop,smembers
- scard 计算集合大小
- sismember 判断元素是否在集合中
- srandmember 从集合中随机挑count个元素
- 不会破坏集合元素
- spop 从集合中随机弹出一个元素
- 从集合中弹出
- smembers 获取集合所有元素
- 无序
- 小心使用(会堵塞)
- 集合内的API和实战
-
- 实战-抽奖系统(spop):
- 实战-Like、赞、踩:
- 进行操作后存在文章的集合中。
- 也可以使用集合、有序集合、列表。
- 实战-标签(tag)
- 小心使用这些命令,防止阻塞。
- care size
- care smembers
- 集合间API和实战
- sdiff,sinter,sunion
- 差集、交集、并集
-
- 实战-共同关注
- 总结 TIPS
- 标签:sadd = Tagging
- 随机数:spop/srandmember = Random item
- 社交相关:sadd + sinter = Social Graph
+ 有序集合类型
- 特点
- 有序集合结构
-
- 对比
- 集合 Vs 有序集合
-
- 列表 Vs 有序集合
-
- 重要API
> 以 z 开头
- zadd 添加score和element(可以多个)。
-
- zrem 删除元素(可以多个)
-
- zscore 返回元素的分数
-
- zincrby 增加或减少元素的分数
-
- zcard 返回元素的总个数
-
- zrank 获取某元素的排名(从小到大)
- 代码示范:
-
- zrange 返回指定索引范围内的升序元素[分值]
-
- zrangebyscore key minScore maxScore [WITHSCORES] 返回指定分数范围内的升序元素[分值]
-
- zcount key minScore maxScore 返回有序集合内在指定分数范围内的个数
-
- zremrangebyrank 删除指定排名内的升序元素
-
- zremrangebyscore 删除指定分数内的升序元素
-
- 代码示范:
-
- 实战
-
- 查漏补缺
- zrevrank key member
- 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。
- zrevrange key start stop [WITHSCORES]
- 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递减(从大到小)来排列。
- zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
- 返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。
- zinterstore destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
- 计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination。默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之和.
- 文档:http://doc.redisfans.com/sorted_set/zinterstore.html
- zunionstore destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
- 计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之 和 。
- 文档:http://doc.redisfans.com/sorted_set/zunionstore.html
- 有序集合 总结
-
# 第三章 Redis 客户端的使用
> 略过
# 第四章 瑞士军刀 Redis 的其他功能
## 慢查询
> 找到系统中瓶颈的命令
- 生命周期
- 两个配置
- slowlog-max-len
\1. 先进先出队列
\2. 固定长度
\3. 保存在内存中
- 三个命令
- 运维经验
## pipeline
## 发布订阅
## Bitmap
## HyperLogLog
## GEO
+ GEO 是什么
-
- 应用场景
-
+ 5个城市经纬度
+ 相关命令
- geoadd : 添加坐标
- geopos : 获取坐标
- geodist : 计算两地的距离
- georadius : 获取指定位置范围内的地址位置信息集合
+ 相关说明
- since 3.2+ (version)
- type getKey = zset (geo使用zset方式实现)
- 没有删除API:zrem key member (可以使用zset的API)
# 第五章 Redis 持久化的取舍和选择
## 持久化的作用
## AOF
## RDB
## RDB和AOF的抉择
# 第六章 常见的持久化开发运维问题
## fork 操作
## 进程外的开销
## AOF 追加阻塞
## 单机多实例部署
# 第七章 Redis 复制的原理与优化
# 第八章 Redis Sentinel
## 主从复制高可用?
## 架构说明
## 安装配置
## 客户端连接
## 实现原理
## 常见开发运维问题
# 第九章 初始 Redis Cluster
## 呼唤集群
## 数据分布
## 搭建集群
## 集群伸缩
## 客户端路由
## 集群原理
## 开发运维常见问题
# 第十章 深入 Redis Cluster
## 伸缩原理
## 扩容集群
## 缩容集群
# 第十一章 缓存设计与优化
## 缓存的受益与成本
## 缓存更新策略
## 缓存粒度控制
## 缓存穿透优化
## 无底洞问题优化
## 缓存雪崩优化
## 热点 key 重建优化
# 第十二章 Redis 云平台CacheCloud
## Redis 规模化运维
## 快速构建
## 机器部署
## 应用接入
# 第十三章 课程总结
\1. Redis 初始:单机安装部署(版本选择),边界(使用场景)。
\2. API理解和使用:单线程、5中数据结构使用和选择。
\3. Redis客户端使用:jedis、redis-py等,客户端很“简单”。
\4. 瑞士军刀Redis:慢查询、pipeline、发布订阅、bitmap等。
\5. Redis持久化:RDB和AOF的优缺点和最佳实践。
\6. Redis 复制:配置方法、全量和部分复制、常见运维问题。
\7. Redis Sentinel:高可用、架构、“新”的客户端、基本原理。
\8. Redis Cluster: 数据分布、架构、安装部署、扩容、客户端、常见问题。
\9. 缓存设计与优化:粒度、更新策略、无底洞问题、穿透、雪崩、热点key。
\10. CacheCloud: 平台化Redis开发运维工具。