Redis真的是单线程吗?

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis真的是单线程吗?

简介

Redis,全名REmote DIctionary Server,开源的高性能的KV内存数据库,支持数据持久化。

开源的支持多种数据结构的基于键值的存储服务系统,高性能、功能丰富。


提供了Java , C/C++ , C# , PHP , JavaScript ,Perl, Object-C , Python , Ruby , Erlang等客户端


  • 从2010年3月15日起, Redis的开发工作由VMware主持
  • 从2013年5月开始, Redis的开发由Pivotal赞助


1 高性能

  • 底层使用ANSI C语言编写,纯内存数据库,所以读取速度快
  • 通讯采用epolI非阻塞I/O多路复用机制,减少了线程切换时上下文的切换和竞争
  • Redis采用单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争
  • Redis存储结构多样化,不同的数据结构对数据存储进行了优化加快读取的速度
  • Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。


Redis能读的速度是11w次/s,写的速度是81000次/s。


官方bench-mark数据:测试完成了50个并发执行100000个请求。设置和获取的值是一个256字节字符串。

结果:读的速度是10000次/s,写的速度是81000次/s。redis尽量少写多读,符合缓存的适用要求。单机redis支撑万级, 如果10万+可采用主从复制的模式。

单线程

Redis 作为一个进程,一直是多线程的。

IO线程

  • redis 6前(2020年5月),单线程
  • redis 6后,多线程,NIO模型 ==> 主要的性能提升点

内存处理线程

  • 单线程
    高性能的核心

原因

  • 无需各种锁的性能消耗
  • 单线程多进程的集群方案
  • CPU 消耗

单进程单线程优势

  • 代码更清晰,处理逻辑更简单
  • 不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
  • 不存在多进程或者多线程导致的切换而消耗CPU

单进程单线程弊端

  • 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善

2 线程安全

Redis 操作都是单线程,原子性的。多线程其实体现在数据解析和同步数据。底层内部的核心操作还是单线程的。

3 丰富的功能

3.1 数据结构

string、hash、list、set、sorted set,raw、int、ht、zipmap、linkedlist、ziplist、intset。

3.2 持久化

  • RDB持久化
  • AOF持久化
  • 4.0 引入RDB- AOF混合持久化

3.3 主从模式

3.4 哨兵

集群

模块化

4 适用场景

缓存、分布式锁、队列、集合、GEO、BitMap、消息队列等。

  • 主流互联网微服务架构下的 redis

image.png

常见缓存中间件对比

1.png

发展史

Redis2.6

1)键的过期时间支持毫秒。

2)从节点支持只读功能。

Redis2.8

1)可以用bind命令绑定多个IP地址。

2)发布订阅添加了pub/sub.

3) Redis Sentinel第二版, 相比于Redis2.6的Redis Sentinel, 此版本已经变成生产可用。

Redis3.0 (里程碑)

  1. Redis最大的改动就是添加Redis的分布式实现Redis Cluster。

Redis3.2

Redis3.2在2016年5月6日正式发布,相比于Redis3.0主要特征如下:

1)添加GE0相并功能。

2)新的List编码类型: quicklist.

Redis4.0 (重大改版)

1)提供了模块系统,方便第三方开发者拓展Redis的功能。

2)提供了新的缓存剔除算法: LFU (Last Frequently Used),并对已有算法进行了优化。

3)提供了非阻塞del和flushall/flushdb功能,有效解决删除了bigkey可能造成的Redis阻塞。

4)提供了RDB-AOF混合持久化格式,充分利用了’AOF和RDB各自优势。

Redis5.0

1)新的Stream数据类型。

2)客户经常连接和断开连接时性能更好。

Redis6.0

  1. 多线程。多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。

使用场景

业务数据缓存

  • 通用数据缓存
    string,int,list,map
  • 实时热数据,最新N条数据
  • 会话缓存,token缓存

业务数据处理

  • 非严格一致性要求的数据:评论,点击等
  • 业务数据去重:订单处理的幂等校验等
  • 业务数据排序:排名,排行榜等

全局一致计数

  • 全局流控计数
    简单的限流组件
  • 秒杀的库存计算
  • 抢红包
  • 全局ID生成

高效统计计数

  • id去重
    记录访问ip等全局bitmap操作
  • UV、PV等访问量
    非严格一致性要求

发布订阅与Stream

  • Pub-Sub 模拟队列 subscribe comments publish comments java

image.png

image.png

分布式锁

  • 获取锁 原子性操作
    SET dlock my_random_value NX PX 30000
  • 释放锁,lua脚本,保证原子性+单线程,从而具有事务性
if redis.call("get",KEYS[1]) == ARGV[1] then 
  return redis.call("del",KEYS[1]) 
else 
  return 0 
end 

关键点:原子性、互斥、超时

Redis Lua

类似于数据库的存储过程,mongodb的js脚本。

open resty = nginx + lua jit。

直接执行

eval "return'hello java'" 0 
eval "redis.call('set',KEYS[1],ARGV[1])" 1 lua-key lua-value

预编译

script load script脚本片段

返回一个SHA-1签名 shastring

evalsha shastring keynum [key1 key2 key3 ...] [param1 param2 param3 ...]

客户端

Jedis

官方客户端,类似于JDBC,可以看做是对redis命令的包装。 基于BIO,线程不安全,需要配置连接池管理连接。

Lettuce

目前主流推荐的驱动,基于Netty NIO,API线程安全。

Redission

基于Netty NIO,API线程安全。

大量分布式功能特性,比如JUC的线程安全集合和工具的分布式版本,分布式的基本数据类型和锁等。

Spring Data Redis

核心是 RedisTemplate(可以配置基于Jedis,Lettuce,Redisson) 使用方式类似于MongoDBTemplate,JDBCTemplate或JPA 封装了基本redis命令操作。

Spring Boot与Redis集成

引入 spring-boot-starter-data-redis

配置 spring redis

Spring Cache与Redis集成

默认使用全局的CacheManager自动集成。


使用ConcurrentHashMap或ehcache时,不需要考虑序列化问题。

使用Redis需要注意


  • 默认使用java的对象序列化,对象需要实现Serializable
  • 自定义配置,可以修改为其他序列化方式
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
监控 NoSQL 安全
如何在 Redis 中正确使用多线程?
【10月更文挑战第16天】正确使用 Redis 多线程需要综合考虑多个因素,并且需要在实践中不断摸索和总结经验。通过合理的配置和运用,多线程可以为 Redis 带来性能上的提升,同时也要注意避免可能出现的问题,以保障系统的稳定和可靠运行。
51 2
|
2月前
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
51 1
|
3月前
|
消息中间件 存储 NoSQL
剖析 Redis List 消息队列的三种消费线程模型
Redis 列表(List)是一种简单的字符串列表,它的底层实现是一个双向链表。 生产环境,很多公司都将 Redis 列表应用于轻量级消息队列 。这篇文章,我们聊聊如何使用 List 命令实现消息队列的功能以及剖析消费者线程模型 。
99 20
剖析 Redis List 消息队列的三种消费线程模型
|
2月前
|
存储 运维 NoSQL
Redis为什么最开始被设计成单线程而不是多线程
总之,Redis采用单线程设计是基于对系统特性的深刻洞察和权衡的结果。这种设计不仅保持了Redis的高性能,还确保了其代码的简洁性、可维护性以及部署的便捷性,使之成为众多应用场景下的首选数据存储解决方案。
42 1
|
2月前
|
NoSQL Redis 数据库
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
本文解释了Redis为什么采用单线程模型,以及为什么Redis单线程模型的效率和速度依然可以非常高,主要原因包括Redis操作主要访问内存、核心操作简单、单线程避免了线程竞争开销,以及使用了IO多路复用机制epoll。
52 0
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
|
3月前
|
NoSQL 网络协议 Unix
1)Redis 属于单线程还是多线程?不同版本之间有什么区别?
1)Redis 属于单线程还是多线程?不同版本之间有什么区别?
80 1
|
3月前
|
存储 消息中间件 NoSQL
Redis的单线程设计之谜:高性能与简洁并存
Redis的单线程设计之谜:高性能与简洁并存
46 1
|
5月前
|
消息中间件 缓存 NoSQL
Redis快速度特性及为什么支持多线程及应用场景
Redis快速度特性及为什么支持多线程及应用场景
119 11
|
4月前
|
缓存 开发框架 NoSQL
【Azure Redis 缓存】Azure Redis 异常 - 因线程池Busy而产生的Timeout异常问题
【Azure Redis 缓存】Azure Redis 异常 - 因线程池Busy而产生的Timeout异常问题
|
4月前
|
NoSQL 关系型数据库 MySQL
简述redis的单线程模式
简述redis的单线程模式