Redis教程(万字图文全面详解)

Redis教程(万字图文全面详解)-mikechen

Redis介绍

Redis 是一个开源的,使用C语言编写的,支持网络交互的、可基于内存也可持久化的Key-Value数据库存储系统。

 

Redis特点

  1. Redis 提供了多种数据类型,比如:字符串(strings),散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)等;
  2. Redis支持数据的持久化,可以将内存中的数据保存在磁盘中;
  3. Redis数据读写速度非常快,因为它把数据都读取到内存当中操作;
  4. Redis支持数据的备份,即master-slave模式的数据备份;
  5. Redis还支持事务 、持久化、LUA脚本、多种集群方案等。

 

Redis应用场景

  1. Redis用作缓存,由于内存的操作,可以减少数据库频繁访问读取的压力。
  2. Redis分布式锁,分布式锁的方案很多,基于Redis实现的分布式锁一般用得最多。
  3. Redis用于计数器 ,基于incr原理每次访问不断累加,可以统计网站访问量,阅读量,点击量等。
  4. Redis用于分布式限流 ,基于incr和expire原理 通过累计单位时间请求次数达到限流。
  5. Redis还可以用于发布订阅,类似若消息队列。
  6. 除此之外可以用于排行、购物车等。

 

Redis安装

Redis window下载地址,点击前往

选择如下图的版本:

Redis教程(万字图文全面详解)-mikechen

2.Redis安装

下载Redis-x64-5.0.14.1.zip 文件,然后 把Redis-x64-5.0.14.1.zip文件解压。

解压后如下图所示:

Redis教程(万字图文全面详解)-mikechen

3.Redis启动

双击 redis-server.exe 启动 Redis,如下图所示:

Redis教程(万字图文全面详解)-mikechen

启动后,如下图所示:

Redis教程(万字图文全面详解)-mikechen

如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了

4.连接Redis

直接双击解压之后文件中的redis-cli.exe,如下图所示:

Redis教程(万字图文全面详解)-mikechen

5.测试Redis

输入ping命令,如下图所示:

Redis教程(万字图文全面详解)-mikechen

能够正确响应pong,则说明redis启动成功了。

 

Redis可视化工具

RedisDesktopManager 是一个快速、简单、支持跨平台的 Redis 桌面管理工具,基于 Qt 5 开发,支持通过 SSH Tunnel 连接,也被称作 Redis 可视化工具。

RedisDesktopManager特点:

  • 适用于 Mac OS、Windows 和 Linux 的 GUI 应用程序
  • 适用于大数据量,你在 redis 中有超过一百万个 key 吗?RDM 管理不成问题
  • 直接或通过 SSH 隧道连接到 Redis
  • 可与 Amazon ElastiCache、Microsoft Azure Redis Cache 和 Redis Labs 配合使用

RedisDesktopManager快速预览

Redis教程(万字图文全面详解)-mikechen

有很多个数据库,插入数据如果不指定数据库的话,默认使用db0

Redis教程(万字图文全面详解)-mikechen

Redis配置

1.绑定的主机地址

bind 127.0.0.1

2.redis监听的端口号

port 6379

3.设置客户端空闲时间

此参数为设置客户端空闲超过timeout,服务端会断开连接,为0则服务端不会主动断开连接,不能小于0。

timeout 300

4.指定日志记录级别

Redis总共支持四个级别:debug、verbose、notice、warning,默认为 verbose。

debug:很多信息,方便开发、测试;

verbose:许多有用的信息, 但是没有debug级别信息多;

notice:适当的日志级别,适合生产环境;

warn:只有非常重要的信息;

比如:

loglevel notice

5.设置数据库的数量

databases 16

默认使用的数据库是0,可以通过 SELECT 【数据库序号】选择一个数据库。

6.是否在后台执行

daemonize yes

yes后台运行,no不是后台运行。

7.指定Redis记录日志文件

logfile /usr/local/redis/var/redis.log

8.设置同一时间最大客户端连接数

maxclients 128

9.指定 Redis 最大内存限制

maxmemory <bytes>

10.指定是否在每次更新操作后进行日志记录

//默认为0
appendonly no

11.指定更新日志文件名

appendfilename appendonly.aof

默认为 appendonly.aof。

12.指定存储至本地数据库时是否压缩数据

//默认为yes
rdbcompression yes

Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大。

13. 指定本地数据库文件名

dbfilename dump.rdb

默认为dump.rdb。

14.设置当本机为 slave 服务

slaveof <masterip> <masterport>

设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步。

15.指定更新日志条件

指定更新日志条件,共有 3 个可选值:

  • no:表示等操作系统进行数据缓存同步到磁盘(快);
  • always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全);
  • everysec:表示每秒同步一次(折衷,默认值);

比如:

appendfsync everysec

16.Redis设置密码

1)通过命令设置密码

config set requirepass 123456

执行完毕无需重启,退出客户端,重新登录就需要输入密码了,这种方式临时有效,重启服务器后密码失效。

2)通过配置设置密码

如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password>命令提供密码,默认关闭。

# The requirepass is not compatable with aclfile option and the ACL LOAD
# command, these will cause requirepass to be ignored.
#
# requirepass foobared

注释打开,设置密码,如下所示:

# The requirepass is not compatable with aclfile option and the ACL LOAD
# command, these will cause requirepass to be ignored.
#
 requirepass 123456

这种方式永久生效。

 

Redis数据类型

Redis支持多种类型的数据结构,最常用的5大数据类型,如下图所示:

Redis教程(万字图文全面详解)-mikechen

1.Redis String数据类型

Sring是Redis最基本的数据类型,二进制安全的字符串,最大512M,可以包含任何数据,比如:字符串、整数、浮点数、图片、Json对象等。

String类型的数据结构是Key-Value(键:值),Key 是数据在Redis中的唯一标识,Value则是其具体的数据。

Redis String常用命令

命令名称

示例

描述

set

set key value

设置键值对

get

get key

获取值

incr

incr key

递增值

decr

decr key

递减值

strlen

strlen key

获取字符串长度

incrby

incrby key increment

增加指定数字

String应用场景

1)计数器

因为 Redis 处理命令是单线程,所以执行命令的过程是原子的,因此 String 数据类型适合计数场景,比如:计算访问次数、点赞、转发、库存数量等等;

2)共享session

分布式Session可以很方便的共享存储session。

3)分布式锁

SET 命令有个 NX 参数可以实现「key不存在才插入」,可以用它来实现分布式锁;

 

2.Redis List数据类型

List列表可以存储有序并且可以重复的元素,按照插入顺序排序,可以从头部或尾部向 List 列表添加元素。

List获取头部或尾部附近的记录是极快的,list的元素个数最多为2^32-1个(40亿)。

redis list常用指令:

常用命令

命令

左压栈

lpush key v1 v2 v3 v4…

右压栈

rpush key v1 v2 …

查看里面的元素

lrange key start offset

左弹栈

lpop key

右弹栈

rpop key

按照索引查找

lindex key index

查看长度

llen key

删除几个几

lrem key 数量 value

指定开始和结束的位置截取,再赋值给key

ltrim key start offset

右出栈左压栈,把resoure的左后一个,压倒dest的第一个

rpoplpush resource destination

重置指定索引的值

lset key index value

在指定元素前/后插入指定元素

linsert key before/after 值1 值2

 

Redis List应用场景

  1. 用户列表,商品列表,评论列表等;
  2. 消息队列;
  3. 栈;

 

3.Redis Set数据类型

Redis Set是无序的字符串集合,不存在重复的元素。

Redis Set常用命令

常用命令

命令

添加值

sadd key values

查看值

smembers key

检查集合是否有值

sismember key value

查看set集合里面的元素个数

scard key

删除集合中的指定元素

srem key value

随机弹出某个元素

srandmember key

随机出栈

spop key

把key1中的某个值赋值给key2

smove SourceSet destSet membe

Redis Set应用场景

Set 类型比较适合用来数据去重和保障数据的唯一性,还可以用来统计多个集合的交集、错集和并集等,当我们存储的数据是无序并且需要去重的情况下,比较适合使用集合类型进行存储。

比如:

  • 统计网站uv;
  • 统计共同好友;

 

4.Redis Sorted Set数据类型

sorted set也叫zset是一个有序集合,元素本身跟set一样,是不重复的。

Sorted Set常用命令

命令

帮助

描述

zadd

zadd key score1 v1 score2 v2 score1v3 … scoren vn

为有序集合添加新成员

zrem

zrem key mem1 mem2 …memn

删除有序集合中指定成员

zcard

zcard key

获得有序集合中的元素数量

zcount

zcount key min max

返回集合中score值在[min,max]区间的元素数量

zincrby

zincrby key increment member

在集合的member分值上加increment

zscore

zscore key member

获得集合中member的分值

zrank

zrank key member

获得集合中member的排名(按分值从小到大)

zrevrank

zrevrank key member

获得集合中member的排名(按分值从大到小)

zrange

zrange key start end

获得集合中指定区间成员,按分数递增排序

zrevrange

zrevrange key start end

获得集合中指定区间成员,按分数递减排序

Sorted Set应用场景

有序列表被广泛使用在各种排行榜业务上:比如销量排行,用户点击率排行等

 

5.Redis Hash数据类型

Redis Hash是key-value对的一种集合,Hash 特别适合用于存储对象。

Redis Hash常用命令

作用

命令

添加单个

hset key field value

获取单个

hget key field

一次性添加多个键值

hmset key field1 value1 field2 value2 …

一次性获取多个

hmget

获取所有键值

hgetall key

删除

hdel

获取键值对的个数

hlen

检查是否包含某个字段

hget key field

查看所有key

hkeys

给某个数值类型(否则报错)的值增加指定整数值

hincrby key field increment

给某个数字类型值,增加指定浮点类型值

hincrbyfloat key field increment

如果不存在则添加

hsetnx

Redis Hash应用场景

比如最典型的就是购物车,以用户 id 为 key,商品 id 为 field,商品数量为 value,恰好构成了购物车的3个要素,如下图所示:

Redis教程(万字图文全面详解)-mikechen

涉及的命令如下:

  • 添加商品:HSET cart:{用户id} {商品id} 1
  • 添加数量:HINCRBY cart:{用户id} {商品id} 1
  • 商品总数:HLEN cart:{用户id}
  • 删除商品:HDEL cart:{用户id} {商品id}
  • 获取购物车所有商品:HGETALL cart:{用户id}

当前仅仅是将商品ID存储到了Redis 中,在回显商品具体信息的时候,还需要拿着商品 id 查询一次数据库,获取完整的商品的信息。

 

 

Redis持久化

Redis的持久化机制有3种:

1.RDB(Redis Data Base) 内存快照

RDB 快照是一次全量备份,RDB快照是内存数据的二进制序列化形式,在存储上非常紧凑。

2.AOF(Append Only File) 增量日志

AOF 则是将每次执行的写命令保存到硬盘,类似于 MySQL 的 Binlog,AOF 持久化的实时性更好,即当进程意外退出时丢失的数据更少。

3.RDB AOF混合持久化

Redis4.0 后大部分的使用场景都不会单独使用 RDB 或者 AOF 来做持久化机制,而是兼顾二者的优势混合使用。

下面针对以上3种Redis持久化机制分别详解。

 

Redis事务

Redis事务有如下三大特性

1.单独的隔离操作

事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

2.没有隔离级别的概念

队列中的命令没有提交之前不会被实际执行,因为事务提交前任何指令都不会被实际执行。

3.不保证原子性

事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。

Redis提供了以下5个基本指令实现事务功能,如下图所示:

Redis教程(万字图文全面详解)-mikechen

 

Redis Lua脚本

Redis 从 2.6 版本开始支持 Lua 脚本,客户端通过 Lua 脚本,可以将多个 Redis 命令组合成一个原子性操作在服务器上执行。

Lua脚本是一种由C编写的可嵌入的轻量级语言, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

典型的Redis分布式锁就会涉及到Lua脚本,以下就是Redisson中RedissonLock加/解锁使用lua的示例。

1.加锁Lua脚本

// 先执行exists key1命令,判断KEYS[1]是否存在
if (redis.call('exists', KEYS[1]) == 0) 
then
    // 不存在,执行hincrby key1 field命令,将ARGV[2]的值原子加1
    // 并设置KEYS[1]的过期时间为ARGV[1]
    // 返回nil
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]); 
    return nil; 
end; 
// 执行hexists key field命令,判断ARGV[2]是否存在
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1)
then 
    // 存在,与上面then逻辑一致
    redis.call('hincrby', KEYS[1], ARGV[2], 1); 
    redis.call('pexpire', KEYS[1], ARGV[1]); 
    return nil; 
end;

// 若key存在且key field也存在,执行pttl key命令,返回KEYS[1]的过期时间
return redis.call('pttl', KEYS[1]);

2.解锁Lua脚本

// 执行hexists key1 field命令,判断判断ARGV[3]是否存在
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) 
then 
    // 不存在,返回nil
    return nil;
end;
// 执行hincrby key1 field命令,获取结果
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); 
if (counter > 0)
then
    // counter大于0,执行pexpire key1 命令,设置key过期时间为ARGV[2]
    redis.call('pexpire', KEYS[1], ARGV[2]);
    return 0;
else 
    // 否则,执行del key命令,删除KEYS[1]
    // 执行publish channel message命令,向KEYS[2]发送消息ARGV[1]
    redis.call('del', KEYS[1]); 
    redis.call('publish', KEYS[2], ARGV[1]);
    return 1;
end;

return nil;

从这两段脚本可以看出Redis集成lua脚本的强大之处,Lua脚本可谓是Redis能力倍增器。

 

Redis主从模式

主从模式是Redis集群模式中最简单的,主从模式指的是使用一个Redis实例作为主机,其余的实例作为备份机,主机和从机的数据完全一致。

如下图所示:

Redis教程(万字图文全面详解)-mikechen

主机支持数据的写入和读取等各项操作,而从机则只支持与主机数据的同步和读取,也就是说客户端可以将数据写入到主机,由主机自动将数据的写入操作同步到从机。

 

Redis主从复制工作原理

Redis教程(万字图文全面详解)-mikechen

  • 当slave启动后主动向master发送SYNC命令;
  • master接收到SYNC命令后在后台保存快照和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave;
  • slave接收到快照文件和命令后加载快照文件和缓存的执行命令;
  • 复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。

 

Redis哨兵模式

为什么需要哨兵模式?

刚刚上面讲到了主从模式当主服务器宕机后,需要手动把一台从服务器切换为主服务器,需要人工干预费事费力,为了解决这个问题出现了哨兵模式。

如下图所示:

Redis教程(万字图文全面详解)-mikechen

哨兵模式由一个或多个Sentinel实例组成的Sentinel系统,它可以监视所有的Master节点和Slave节点,并在被监视的Master节点进入下线状态时,自动将下线Master服务器。

哨兵模式工作原理

当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。

如下图所示:

Redis教程(万字图文全面详解)-mikechen
  1. 哨兵机制建立了多个哨兵节点(进程),共同监控数据节点的运行状况。
  2. 同时哨兵节点之间也互相通信,交换对主从节点的监控状况。
  3. 每隔1秒每个哨兵会向整个集群:Master主服务器+Slave从服务器+其他Sentinel(哨兵)进程,发送一次ping命令做一次心跳检测。

 

Redis集群模式

为什么需要Redis集群模式

哨兵模式基于主从模式,实现读写分离,它还可以自动切换,系统可用性更高。但是它每个节点存储的数据是一样的,浪费内存,因此在Redis3.0后Cluster集群应运而生。

Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。

 

Redis集群模式原理

在Redis的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383,还有一个就是cluster。

如下图所示:

Redis教程(万字图文全面详解)-mikechen

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法