# 一站式学习Redis 从入门到高可用分布式实践

> https://coding.imooc.com/class/151.html

系统学习Redis必备,企业级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 是什么

- 开源(可定制化)

- 基于键值的存储服务系统

- 多种数据结构

数据结构.png

- 高性能、功能丰富

哪些公司在用Redis.png

+ Redis 的特性回顾

- Redis 的特性

​ - 速度快

​ - 10w OPS(每秒实现10w读写)

​ - 数据存在哪?内存

​ - 什么语言写的?C语言(50000 line)

​ - 线程模型? 单线程

​ - 速度快-内存.png

​ - 持久化

​ - 断电不丢数据

​ - Redis 所有数据包吃在内存中,对数据的更新将异步地保存到磁盘上。

​ - 多种数据结构

​ - 数据结构.png

​ - 多种数据结构-续(新版本):

​ - BitMaps:位图(很小内存高效存储)

​ - HyperLogLog:超小内存唯一值计数

​ - 缺点:计数有误差

​ - GEO:地理信息定位(>3.2版本)

​ - 支持多种编辑语言

​ - 支持多种客户端语言.png

​ - 功能丰富

​ - 发布订阅(消息队列)

​ - Lua 脚本(自定义命令)

​ - 事务

​ - pipeline(指的是管道技术,指的是客户端允许将多个请求依次发给服务器,过程中而不需要等待请求的回复,在最后再一并读取结果即可。)

​ - redis通过pipeline提升吞吐量

​ - 简单

​ - 23000 lines of code(23000行代码)

​ - 不依赖外部库(like libevent)

​ - 单线程

​ - 主从复制

​ - 高可用、分布式

​ - 高可用 Redis-Sentine(v2.8)支持高可用

​ - 分布式 Redis-Cluster(v3.0)支持分布式

+ Redis 典型使用场景

> Redis应用场景1——简单场景

- 缓存系统

​ - 对相关数据进行缓存

- 计数器

​ > 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客户端连接.png

​ - redis客户端返回值.png

​ - redis客户端返回值2.png

- redis 常用配置

​ - daemonize > 是否是守护进程(no|yes)

​ - port > Redis 对外端口号

​ - logfile > Redis 系统日志

​ - dir > Redis 工作目录

​ - 端口号:6379 ?

​ - redis默认端口号.png

​ - 其他配置:

​ - RDB config

​ - AOF config

​ - slow Log config

​ - maxMemory

​ - …

# 第二章 API的理解和使用

## 课程目录

### Redis API 的使用和理解

+ 通用命令

- 通用命令

​ - keys > 计算 Redis 库的所有的键

​ - keys * 遍历所有的key

​ - keys [pattern] 遍历所有key

​ > pattern 可以当做通配符

​ - keys后续1.png

​ - keys 命令一般不在生产环境使用

​ - keys * 怎么使用

​ - 热备从节点

​ - scan

​ > Redis中的Scan命令的使用

​ > - Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式。

​ > - 一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行的,keys是以遍历的方式实现的复杂度是 O(n),Redis库中的key越多,查找实现代价越大,产生的阻塞时间越长。

​ > - 二是scan命令,以非阻塞的方式实现key值的查找,绝大多数情况下是可以替代keys命令的,可选性更强

​ - dbsize > 计算库的总数

​ - dbsize.png

​ - exists key > 判断一个 key 是否存在

​ - exists.png

​ - del key [key …] > 删除多个 key

​ - del.png

​ - expire key seconds > 设置 key 过期时间

​ - expire.png

​ - expire-1.png

​ - expire-2.png

​ - type key > 设置 key 类型

​ - type.png

​ - 时间复杂度

​ - 时间复杂度.png

- 数据结构和内部结构编码

​ - 数据结构和内部编码.png

​ - redisObject.png

- 单线程架构

​ - Redis 单线程,

​ - 一瞬间只执行一条命令(串行结果),不会执行多条。

​ - 单线程.png

​ - 单线程为什么这么快?

​ - 纯内存

​ - 非阻塞IO

单线程.png

​ - 避免线程切换和竞态消耗

​ - 单线程需要注意什么?

​ - 一次只运行一条命令

​ - 拒绝长(慢)命令(数据过多时响应过久)

​ > keys,flushall,flushdb,slow lua script,mutil/exec,operate big value(collection)

​ - 其实不是单线程(执行以下操作时,会有独立的线程操作)

​ - fusnc file descriptor

​ - close file descriptor

+ 字符串类型

- 结构和命令

​ - 字符串键值结构

​ - 字符串值最大512MB,建议100kb左右。

​ - 字符串键值结构.png

​ - 场景

​ - 缓存

​ - 计数器

​ - 分布式锁

​ - 等等

​ - 命令

​ - get,set,del

​ - get,set,delpng.png

​ - get,set,del演示.png

​ - incr,decr,incrby,decrby

​ - 命令2演示.png

​ - 命令2.png

​ - 快速实战

​ - 实现如下功能:

​ - 1. 记录网站每个用户个人主页的访问量?

​ - incr userid:pageview(单线程:无竞争)每个命令独立执行,不会记错数。

​ - 2. 缓存视频的基本信息(数据源在MySQL中)伪代码。

​ - 实战1.png

​ - 实战1代码.png

​ - 3. 分布式ID生成器。

​ > 每次获取到的ID自增,三个应用并发获取。

​ - 分布式ID.png

​ - incr id(原子操作)

​ - set,setnx,set xx

​ - 命令4.png

​ - 命令4演示.png

​ - mget,mset

​ - 命令5.png

​ - 命令5范例.png

​ - 1次mget.png

​ - n次get.png

- 内部编码

- 查漏补缺

​ - getset,append,strlen

​ - 命令6.png

​ - 命令6演示.png

​ - incrbyfloat,getrange,setrange

​ - 命令7.png

​ - 命令7演示.png

- 字符串总结

​ - 字符串总结.png

+ 哈希类型

- 结构

​ - 哈希键值结构.png

​ - 哈希键值1.png

- 特点

​ - 哈希特点.png

- 重要API

​ - hget,hset,hdel

​ - 命令.png

​ - 命令演示.png

​ - hexists,hlen

​ - 命令2.png

​ - 命令2演示.png

​ - hmget,hmset

​ - 命令3.png

​ - 命令3演示.png

​ - hgetall,hvals,hkeys

​ - 命令11.png

​ - 命令11演示.png

- hash vs string

​ - 对比.png

​ - 以 用户更新用户属性?三种方案:

​ - 1. 对比1.png

​ - 2. 对比2.png

​ - 3. 对比3.png

​ - 三种方案比较:

​ - 对比5.png

- 查漏补缺

​ - hsetnx,hincrby,hincrbyfloat

​ - 命令12.png

- 实战功能:

​ - 1. 记录网站每个用户个人主页的访问量?

​ - hincrby user:1:info pageview count

​ - 2. 缓存视频的基本信息(数据源在MySQL中)伪代码

​ - 命令4代码.png

- 哈希总结

​ - 哈希总结.png

+ 列表类型

- 列表结构

​ - 有序列表

1.png

​ - 可以左插入、弹出和右插入、弹出。

2.png

​ - 计算长度

3-计算列表长度png.png

​ - 删除指定一个元素

4--删除一个元素.png

​ - 获取列表的一个子列表

5获取子元素.png

​ - 根据索引获取列表的指定元素

6--获取指定元素.png

- 特点

7--特点.png

- 重要API

​ - 都以 L 开头,先以增删改插为例:

​ - 增:

​ - rpush 从右端插入值

API--1.png

​ - lpush 从左端插入值

API--2.png

​ - linsert 指定的值前/后插入newValue

API--3.png

​ - lpop 从左侧弹出一个item

​ - API--4.png

​ - API--4-1.png

​ - rpop 从右侧弹出一个item

​ - API--5.png

​ - API--5-1.png

​ - 删:

​ - lrem 根据count值,从列表中删除所有value相等的项

​ - API--6.png

​ - API--6-1.png

​ - API--7.png

​ - ltrim 按照索引范围修剪列表

​ - API--8.png

​ - API--8-1png.png

​ - API--9.png

​ - 查:

​ - lrange 获取指定索引范围所有item

API--10.png

​ - 获取索引0~2的数据

API--10-1.png

​ - 获取索引1~-1的数据

API--10-2.png

​ - lindex 获取指定索引的item

​ - API--11.png

​ - API--11-1.png

​ - llen 获取列表长度

API--12.png

​ - 改:

​ - lset 设置列表指定索引的值为newValue

​ - API--13.png

​ - API--14.png

- 实战

​ - 实战--1.png

​ - 实战--2png.png

- 查漏补缺

​ - blpop lpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞

查漏补缺.png

​ - brpop rpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞

- 列表总结 TIPS

​ \1. 栈:LRUSH + LPOP = Stack

​ \2. 队列:LPUSH + RPOP = Queue

​ \3. 控制一个有固定数量的队列(防止无限放大),控制列表大小:LPUSH + LTRIM = Capped Collection

​ \4. 消息队列:LPUSH + BRPOP = Message Queue

+ 集合类型

- 集合结构

​ - 集合结构.png

​ - 添加元素.png

​ - 添加重复元素.png

​ - 删除元素.png

​ - 数据操作--1.png

- 特点

特点.png

- 命令

​ > 以 s 开头

​ - sadd,srem

命令.png

​ - sadd 向集合key添加元素(如果元素已存在则添加失败)

​ - srem 将集合key中的元素移除掉

​ - scard,sismember,srandmember,spop,smembers

命令2.png

​ - scard 计算集合大小

​ - sismember 判断元素是否在集合中

​ - srandmember 从集合中随机挑count个元素

​ - 不会破坏集合元素

​ - spop 从集合中随机弹出一个元素

​ - 从集合中弹出

​ - smembers 获取集合所有元素

​ - 无序

​ - 小心使用(会堵塞)

- 集合内的API和实战

​ - 集合内的实战.png

​ - 实战-抽奖系统(spop):

抽奖系统.png

​ - 实战-Like、赞、踩:

1QjFHS.png

​ - 进行操作后存在文章的集合中。

​ - 也可以使用集合、有序集合、列表。

​ - 实战-标签(tag)

1QjlHU.png

​ - 小心使用这些命令,防止阻塞。

​ - care size

​ - care smembers

- 集合间API和实战

​ - sdiff,sinter,sunion

​ - 差集、交集、并集

​ - 1Qj5VS.png

​ - 实战-共同关注

1Qv9PJ.png

- 总结 TIPS

​ - 标签:sadd = Tagging

​ - 随机数:spop/srandmember = Random item

​ - 社交相关:sadd + sinter = Social Graph

+ 有序集合类型

- 特点

​ - 有序集合结构

​ - 有序集合结构.png

​ - 对比

​ - 集合 Vs 有序集合

​ - 对比1.png

​ - 列表 Vs 有序集合

​ - 对比2.png

- 重要API

​ > 以 z 开头

​ - zadd 添加score和element(可以多个)。

​ - zadd.png

​ - zrem 删除元素(可以多个)

​ - zrem.png

​ - zscore 返回元素的分数

​ - zscore.png

​ - zincrby 增加或减少元素的分数

​ - zincrby.png

​ - zcard 返回元素的总个数

​ - zcard.png

​ - zrank 获取某元素的排名(从小到大)

​ - 代码示范:

​ - 案例.png

​ - zrange 返回指定索引范围内的升序元素[分值]

​ - zrange.png

​ - zrangebyscore key minScore maxScore [WITHSCORES] 返回指定分数范围内的升序元素[分值]

​ - zrangebyscore.png

​ - zcount key minScore maxScore 返回有序集合内在指定分数范围内的个数

​ - zcount.png

​ - zremrangebyrank 删除指定排名内的升序元素

​ - zremrangebyrank.png

​ - zremrangebyscore 删除指定分数内的升序元素

​ - zremrangebyscore.png

​ - 代码示范:

​ - 案例代码2.png

- 实战

​ - 实战--排行榜.png

- 查漏补缺

​ - 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

- 有序集合 总结

​ - 总结.png

# 第三章 Redis 客户端的使用

> 略过

# 第四章 瑞士军刀 Redis 的其他功能

## 慢查询

> 找到系统中瓶颈的命令

- 生命周期

- 两个配置

​ - slowlog-max-len

​ \1. 先进先出队列

​ \2. 固定长度

​ \3. 保存在内存中

- 三个命令

- 运维经验

## pipeline

## 发布订阅

## Bitmap

## HyperLogLog

## GEO

+ GEO 是什么

- GEO是什么

- 应用场景

​ - 应用场景

+ 5个城市经纬度

5个城市经纬度

+ 相关命令

- geoadd : 添加坐标

geoadd

- geopos : 获取坐标

geopos

- geodist : 计算两地的距离

geodist

- georadius : 获取指定位置范围内的地址位置信息集合

georadius--api

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开发运维工具。