解锁 Redis:探索连接策略、数据编码与性能秘诀
探索连接策略、数据编码与性能秘诀
- 一 . Redis 常见客户端介绍
- 二 . 认识数据类型和编码方式
- 2.1 Redis 中的数据类型以及对应的内部编码
- 2.2 通过命令查看具体编码方式
- 三 . Redis 的单线程模型
- 3.1 Redis 是否存在线程安全问题 ?
- 3.2 单线程为什么这么快 ?
Hello , 大家好 , 这个专栏给大家带来的是 Redis 系列 ! 本篇文章是想在正式介绍 Redis 的数据结构之前 , 探讨一下 Redis 连接具体有多少种方式、怎样查看具体某个数据结构的编码规则、Redis 快的原因 , 了解了这些之后才能更好地理解 Redis 的常见数据结构 .
本专栏旨在为初学者提供一个全面的 Redis 学习路径,从基础概念到实际应用,帮助读者快速掌握 Redis 的使用和管理技巧。通过本专栏的学习,能够构建坚实的 Redis 知识基础,并能够在实际学习以及工作中灵活运用 Redis 解决问题 .
专栏地址 : Redis 入门实践
一 . Redis 常见客户端介绍
那我们首先要明确 , Redis 也是一个 “客户端-服务器” 结构的程序
比如 : 我们之前学习过的 MySQL , 也是一个客户端-服务器结构的程序
那他的基本结构就如下 :
那 Redis 的客户端也有很多种
- 自带的命令行客户端 : redis-cli
[root@VM-8-16-centos ~] redis-cli # 启动 Redis 客户端
[root@VM-8-16-centos ~] redis-cli -h 127.0.0.1 -p 6379 # 启动其他主机的 Redis 客户端
- 图形化界面的客户端
- 基于 Redis 的 API 自行开发的客户端
类似于 MySQL 的 JDBC
二 . 认识数据类型和编码方式
我们常见的 Redis 的数据结构如下 :
键是 string 类型的 , 而 value 有好几种类型 , 常见的有 : string、hash、list、set、zset 等
那他跟我们 Java 中的数据类型可以类比理解
字符串 <-> String
哈希 <-> HashMap
列表 <-> 类似 List
集合 <-> Set
有序集合 <-> 类似 Set , 需要额外存储一个 score (权重 / 分数)
那 Redis 底层在实现上述的数据结构的时候 , 会在源码层面针对上述实现进行特定优化 , 达到节省时间 / 节省空间的效果 , 也就是说底层的编码方式不一定就是按照该数据类型进行设计的
比如 : 官方说我们的哈希增删改查时间复杂度都是 O(1) , 但是他的底层实现就不一定通过 HashMap 去实现的 , 只是人家通过不断的操作最终让时间复杂度变成了 O(1)
那我们就先了解一下每种数据类型的内部编码方式如何
2.1 Redis 中的数据类型以及对应的内部编码
数据类型 | 内部编码 |
---|---|
string | raw |
int | |
embstr | |
hash | hashtable |
ziplist | |
list | linkedlist |
ziplist | |
set | hashtable |
intset | |
zset | skiplist |
ziplist |
2.2 通过命令查看具体编码方式
我们可以通过 object encoding key 的方式来去看一下 value 的实际编码方式
127.0.0.1:6379> set k1 111 # 设置 k1 为数字
OK
127.0.0.1:6379> type k1 # 查看 k1 的类型虽然是 string 类型
string
127.0.0.1:6379> object encoding k1 # 但是底层的实现是 int 来去实现的
"int"
127.0.0.1:6379> lpush k2 one # 设置 k2 为列表
(integer) 1
127.0.0.1:6379> type k2 # 查看 k2 的类型虽然是 list 类型
list
127.0.0.1:6379> object encoding k2 # 但是底层的实现是 quicklist 来去实现的
"quicklist"
127.0.0.1:6379> sadd k3 111 # 设置 k3 为集合
(integer) 1
127.0.0.1:6379> type k3 # 查看 k3 的类型虽然是 set 类型
set
127.0.0.1:6379> object encoding k3 # 但是底层的实现是 intset 来去实现的
"intset"
127.0.0.1:6379> hset k4 field1 1 # 设置 k4 为哈希
(integer) 1
127.0.0.1:6379> type k4 # 查看 k4 的类型虽然是哈希类型
hash
127.0.0.1:6379> object encoding k4 # 但是底层的实现是 ziplist 来去实现的
"ziplist"
三 . Redis 的单线程模型
3.1 Redis 是否存在线程安全问题 ?
Redis 的单线程模型指的是 Redis 只使用一个线程来去处理所有的命令请求
不是说 Redis 服务器内部只有一个线程
假设我们现在有多个客户端同时在与服务器进行交互
3.2 单线程为什么这么快 ?
效率高 / 速度快是与 MySQL 等数据库相比较的
- Redis 主要是访问内存 , 数据库则是访问硬盘的
- Redis 的核心功能比数据库的核心功能更加简单
- Redis 是单线程模型 , 他避免了一些不必要的线程竞争开销
- 处理网络 IO 的时候 , 使用了 IO 多路复用机制
IO 多路复用指的是一个线程 , 就可以管理多个 socket
那针对 TCP 来说 , 服务器每次要服务一个客户端 , 都需要给这个客户端安排一个 socket
那一个服务器要服务多个客户端 , 同时就有很多的 socket , 那这些 socket 都是无时无刻在传输数据吗 ?
其实很多情况下 , 每个客户端和服务器之间的通信也不是特别频繁 , 那大部分 socket 在很长一段时间都是静默的 , 是没有数据需要传输的 .
也就是说 , 同一时刻只有少数 socket 是活跃的 , 这是我们 IO 多路复用的前提 .
那我们 IO 多路复用就是让一个线程来去处理多个 socket , 那具体的处理方式如下 :
不知道大家吸收如何 , 如果对您有帮助的话 , 请多多支持~