Redis总体介绍,配置以及基本使用方法
1、Redis基本介绍
Redis是开源的,位于内存中的数据结构存储系统。主要用于数据缓存、消息中间件。内置LUA脚本(支持原子性操作)、LRU驱动事件、事务和不同级别的磁盘持久化,Redis也可以通过哨兵和自动化分区提供高可用性。
Redis为什么快
首先,Redis给我们的第一印象就是快,非常快,位于内存的IO操作可以达到秒级十万的操作,从内存上的寻址速度可以达到ns级别,带宽很大,而一般sql型数据库则是从磁盘上寻址,速度则是ms级别,所以磁盘相比内存在寻址上慢了10万倍。
磁盘数据库如Mysql,数据和索引都是持久化保存在磁盘上的,当我们使用SQL语句查询命令时,若该数据的索引还没加载到内存,首先要把索引加载到内存,然后通过寻址定位和IO,将数据对应的磁盘块加载到内存中,最后读取数据。
Redis在内存中读取数据,是电信号的传递。
1.1、 Redis内核架构
epoll介绍
epoll作为Linux下高性能网络服务器必备技术至关重要。nginx、Redis、skynet 以及大部分的游戏服务器都使用这一多路复用技术。对Redis的IO起到了关键作用。
1.2、 Redis原理
众所周知,Redis是单进程,单线程,单实例的(Redis6之前),那么当高并发的请求发送过来时,Redis如何快速响应?这里面主要用到了epoll多路复用技术,可以理解为多个输入通过一条高速线路,n个信道,分配到多个输出(分为频分,时分,波分),大大提高速度。并且是非阻塞的多路复用。
2、Redis的使用
2.1、Redis数据类型
高效的数据结构
Redis底层数据结构一共有6种:简单动态字符串(StringBuffer),双向链表,压缩列表,哈希表,跳表和整数数组,与之对应的数据类型关系图如下:
不同的数据结构对应了不同的应用场景:
- String: 缓存,分布式锁,在线人数计算等
- List: 队列,微博,Instagram关注人时间轴队列等
- Hash: 收藏,加购物车等
- Set: 去重,点赞(不可重复点赞),踩一踩,共同好友等
- ZSet: 排行榜排名、热搜榜等
Redis的自定义协议
Redis客户端使用RESP(Redis的序列化协议)协议与Redis服务器端进行通信,实现简单、解析快速且人可读。
RESP支持一下数据类型: 简单字符串、错误、整数、批量字符串和数组。
RESP在Redis中运作的方式为:
- 客户端将命令作为批量字符串的RESP数组发送到Redis服务器
- 服务器根据命令实现其中一种RESP类型并进行回复
在RESP中,某些的数据类型取决于第一个字节:
- 对于简单字符串,响应的第一个字节为"+"
- 对于整数,响应的第一个字节为":"
- 对于批量字符串,响应的第一个字节为"$"
- 对于错误,响应的第一个字节为"-"
- 对于数组,响应的第一个字节为"*"
此外,RESP使用特殊变体表示null值。在RESP中,协议的不同部分总是以"\r\n"(CRLF)终止。
高性能Redis协议分析器
快速,高效的解析协议利于阅读,使得该协议的实现性能变得和二进制协议一样快的主要原因是Redis协议将数据的长度定义在了数据正文之前,无需因为寻找特殊字符而进行全文扫描(JSON的payload),也无需像JSON一样对发送到服务器的payload进行转义。
Redis中Value的类型
- 字符串
set k1 xxxx nx.
set k2 Hello xxxx.
nx => 只能新建
xx => 只能更新
append 字符串拼接
GETRANGE
SETRANGE
-
数值
先 set k1 99
OBJECT encoding k1
可以看到是int类型
INCR k1 (数值增加 默认为1)
INCRBY k1 22 (数值增加 增加数值指定)
DECR k1 (减)
DECRBY k1 22
INCRBYFLOAT k1 0.5 -
二进制安全
字符串分为字节流和字符流
STRLEN k1
redis- li --raw
Redis设计里没有数据类型(都包含在String,Byte)
要指定好编码集(UTF-8、GBK)
Redis是二进制安全的(字节数组) -
bitmap (便于运算)
4.1 BITOP(位与,位货,异或)
4.2 BITCOUNT destkey 0 -1 -
List (栈)
lpush
lpop
rpush / pop
LRANGE
LINDEX
LSET
LTPIM -
Hash
set shown::name “xxx”
set shown::age 15
set shown::id 12
对field进行数值计算 -
Set (集合)
sadd k3 1 2 3 4 5 6
SMEMBERS (去所有元素,占用网卡吞吐量建议不要使用)
SINTER k2 k3 (取交集)
SINTERSTORE dest k2 k3 (取交集并放入dest中)
SUNION k2 k3 (并集)
SDIFF k2 k3 (差集) -
Sorted_set
ZADD
ZCARD
ZCOUNT
2.2、Redis的进阶使用
1、 Redis的发布订阅
有这样一个应用场景,聊天室里发布的消息可以让(不管在不在该聊天室窗口)所有人都可以看到,这里就可以用到Redis的发布订阅功能。
PUBLISH xxxx hello
SUBSCRIBE xxxx (监听改Key)
2、 Redis事务
Redis事务的使用帮助 -> help@transactions
Redis事务的和Mysql类似,即将一组命令放在同一事务中,MULTI开启一个事务,这些事务会放在一个队列中,不会立即执行。只有当EXEC命令被调用时,改命令才会被执行。
注意: Redis不支持回滚,Redis命令只会因为错误语法失效
3、 布隆过滤器(Bloom)使用
4、 Redis作为缓存/数据库的区别
- 缓存不是全量数据。缓存应该随着访问而变化 => 热数据
- Redis里的数据怎么随着业务的变化而只保留热数据(内存大小的瓶颈)
业务逻辑 -> key的有效期(过期时间)
业务运行 -> 淘汰冷数据
LFU 碰到了多少次
LRU 多长时间没碰到
ttl k1
如果发生了写命令(SET XXX) 会直接剔除expiretime
Redis每秒10次做一件事 => 随机测试20个keys相关过期检测 => 删除已过期keys =>
若有超过1/4的key过期,则重复操作。 - 过期的判定原理
- 被动访问时判定
- 周期轮询时判定(增量)
3、Redis的持久化(RDB/AOF)
3.1、Redis-RDB(RedisDB)
RDB即Redis的持久化机制,Redis父进程会单独fork(创建)一个子进程(和自己一模一样)来进行持久化。该子进程的所有数据(变量。环境变量,程序程序计数器等)都和父进程一模一样,将数据写入一个快照,等持久化结束后,数据库的快照(snapshot)以二进制的方式保存到磁盘中。用这个快照替换上次持久化好的文件。整个过程中,主进程没有任何IO操作,这就确保了极高的性能。
RDB的主要特征是写时复制(copy on write)
创建紫禁城**(子进程 谐音梗 O(∩_∩)O)**时并不发生复制。
通过指针,父进程增删改查数据(写),子进程读数据。
RDB的弊端
- 不支持拉链结构
- 因为父子进程同步的问题,丢失数据相对多一些
- 相对于Java中的序列化,恢复速度相对没有那么快
3.2、Redis-AOF(APPEND ONLY FILE)
AOF是以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的。
AOF优点:
- 丢失数据少
- Redis中,RDB和AOF可以同时开启,若开启了AOF,则只会用AOF恢复
AOF弊端:
相对于RDB,慢,体量无限地变大
场景复现!!
解决设计思路:
设计方案让日志(AOF)足够小
Redis:
- 4.0之前 -> 重写 -> 删除抵消命令,合并重复命令 -> 纯指令的日志文件
- 4.0之后 -> 重写 -> 将增量的key以指令方式Append到AOF中 -> AOF混合体,利用了RDB的恢复快,AOF的全量特点
3.3、RDB、AOF实操
首先 修改redis配置文件(vim /etc/Redis/redis.conf)
- daemonize no #关闭守护进程
-
logfile … # 注释掉保存日志文件路径,将日志输出到控制台
- save RDB 配置
- appendonly yes # 打开AOF
- aof-use-rdb-preamble no # 混合模式先关闭
3.4、Redis中AKF原理
由于redis是单机,单实例,单进程的。就会造成熟悉的单机问题:单点故障;容量有限;压力大
此时要了解redis的AKF,即业务功能拆分,根据XYZ轴拆分成三个方向。
X: 全量,镜像
Y: 业务,功能
Z: 逻辑优先
这样易造成数据的强一致性,即所有的节点都会阻塞,知道数据全部一致时,但这样就会破坏可用性。要想可用,可用容忍数据丢失一部分,也可以通过异步方式(不是强一致)
4、Redis的主从,哨兵(配置)
4.1、Redis CAP理论
CAP理论,即在一个分布式系统中,一致性(Consistemce)、可用性(Available)、分区容错性(Partition),三者只能同时实现其中两个,不可三者兼顾。
CAP理论是在集群中最常考虑的问题,在主从复制或者主备的集群中,对主节点(机器)做高可用,自动转移故障
4.2、Redis主从模式
4.2.1、Redis主从复制原理
设置从节点(机器)
4.3、Redis集群模式
4.4、Redis哨兵模式
4、Redis缓存问题
缓存击穿,雪崩
5、Spring结合Redis
5.1、 Redis api
参考Spring-data的官方文档。Spring中对于Redis的api支持集成了Lettuce和Jedis的连接,默认连接Lettuce
配置Lettuce连接,首先导入maven依赖
接着在Spring中创建连接工厂
@Configuration
class AppConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
}
}
所有的LettuceConnection连接实例都是默认由LettuceConnectionFactory连接工厂类创建的,对于所有的非阻塞以及非事务操作,所有实例都共享线程安全的连接。LettuceConnectionFactory也可以配置LettucePool连接池
@Configuration
class AppConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock"));
}
}
配置Jedis连接,也是同样的过程,可以在官方文档中查看。
同时Redis的主从/哨兵/集群配置,是Redis常见的配置。通过Lettuce连接,可以完成主从(主写从读)的配置
@Configuration
class WriteToMasterReadFromReplicaConfiguration {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.readFrom(SLAVE_PREFERRED)
.build();
RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration("server", 6379);
return new LettuceConnectionFactory(serverConfig, clientConfig);
}
}
从节点向主节点读
为了构建高可用的Redis服务,Spring Data Redis 使用RedisSentinelConfiguration配置Redis的哨兵
/**
* Jedis
*/
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master("mymaster")
.sentinel("127.0.0.1", 26379)
.sentinel("127.0.0.1", 26380);
return new JedisConnectionFactory(sentinelConfig);
}
/**
* Lettuce
*/
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master("mymaster")
.sentinel("127.0.0.1", 26380);
return new LettuceConnectionFactory(sentinelConfig);
}
更多集群连接的配置可参考官方文档:
https://docs.spring.io/spring-data/redis/docs/2.3.5.RELEASE/reference/html
5.2、 高阶api
越来越多的小伙伴会选择使用高阶的api操作Redis(简单省事呗
原文地址:https://blog.csdn.net/weixin_42182687/article/details/123321449
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。