redis实验环境
针对学习redis 我们可以为您提供一套完善的学习环境
点击此处跳转
章节叙述
本章节主要介绍一下Redis
的一些全局命令,数据库的基本操作,key的基本操作,以及了解一下Redis
的单线程命令处理机制,主要是为了后面内容的学习打下一个比较好的基础。主要体现在两个方面:
- 第一、
Redis
的命令上百个,如果纯靠死记硬背比较困难,但是如果理解Redis
的一些机制,会发现这些命令有很强的通用性。 - 第二、
Redis
不是万金油,有些数据结构和命令必须在特定场景下使用,一旦使用不当可能会对Redis
本身或者应用本身造成致命伤害。
全局命令
为了您可以更好的学习Redis
接下来的课程,我们先简单介绍一些通用指令。 如果您执行了关闭redis-server
服务操作的话,您需要重新启动redis-server
服务,并且使用redis-cli
进入客户端才能继续以下的课程。
1,数据库操作
首先我们先了解一下Redis
默认拥有16个数据库,默认使用的是第一个也就是0号数据库。各个数据库之间是相互独立的,互不影响,没有任何关联。Redis
提供了几个面向Redis
数据库的操作,它们分别是select
,flushdb/flushall
命令,我们依次来介绍一下
-
1,切换数据库
我们已经了解到 使用
redis-cli
进入Redis
客户端后,默认所处的数据库为0号数据库,如果我们想切换所处的数据库的话可以使用如下命令(默认配置是拥有16个数据库,您如果不修改配置文件的话能切换的选择范围是(0-15))select 1
我们可以通过查看当前的输入行前缀查看当前当前所处的数据库,当不位于0号数据库之下时,会在前面[ ]里边显示数据库的编号。
127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> select 0 OK
目前
Redis
已经逐渐弱化这个功能,例如Redis
的分布式实现RedisCluster
只允许使用0号数据库, 只不过为了向下兼容老版本的数据库功能,该功能没有完全废弃掉, 下面分析一下为什么要废弃掉这个“优秀”的功能呢? 总结起来有三点-
Redis
是单线程的,如果使用多个数据库的话,这些数据库仍然是使用的同一个cpu
彼此间还是会受到影响的 -
多数据库的使用方式, 会让调试和运维不同业务的数据库变的困难,假如有一个慢查询存在, 依然会影响其他数据库, 这样会使得别的业务方定位问题非常的困难 。
-
部分
Redis
的客户端根本就不支持这种方式。 即使支持, 在开发的时候来回切换数字形式的数据库, 很容易弄乱。笔者建议如果要使用多个数据库功能, 完全可以在一台机器上部署多个
Redis
实例, 彼此用端口来做区分, 因为现代计算机或者服务器通常是有多个CPU
的。 这样既保证了业务之间不会受到影响, 又合理地使用了CPU
资源。
-
-
2,
flushdb/flushall
flushdb/flushall
命令用于清除数据库,两者的区别的是flushdb
只清除当前数据库,flushall
会清除所有的数据库。以下提供简单的示例首先我们先查询当前数据库是否有值
keys *
如果没有值的我们需要先添加一个。
set key1 value1
然后我们执行
flushdb
命令flushdb
然后查询当前数据库的情况,可以发现确实为空
keys *
接下来我们测试一下
flushall
指令 ,先重新新建一个值set key1 value1
我们使用刚刚学过的指令
select
指令切换一个数据库然后执行flushall
指令 。select 0
flushall
ok,现在我们切换原先的数据库查看一下效果
select 1
keys *
可以发现命令确实生效。
*建议大家使用这两个命令的时候一定要谨慎,慎重。
2,键操作
Redis
有5种基本数据结构分别是String
,Hash
,List
,Set
,Zset
, 它们是键值对中的值, 对于键来说有一些通用的命令
-
1,查看所有键
我们可以通过
key*
来查询当前数据库下的所有键值,下面我们先插入3对字符串类型的键值对:mset key1 value1 key2 value2 key3 value3
随后通过
key *
查询,您就可以得到当前的所以键keys *
*注意生产环境禁止使用此命令,此命令会检索所有的
key
如果Redis
存储的量过多的话会造成Redis
的阻塞,在课程6的附件部分我们会对Redis
的遍历键做简单的分析说明 -
键总数
我们可以通过
dbsize
来查询当前数据库下的键总数dbsize
*
dbsize
指令在计算键总数的时候不会遍历所有键,而是直接获取Redis
内置的键总数变量,所以dbsize
的时间复杂度是 0(1) 。 -
3,检查键是否存在
我们可以用
exists
来检查指定键是否存在,我们先查询刚刚插入的键,exists key1
再查询一个不存在的键
exists key4
通过对比我们可以发现:如果键存在则返回 1 否则返回 0
-
4,删除键
我们可以通过
del
来删除指定键值,操作结果为删除键的个数,支持删除多个。del key1 key2
-
5,键过期
Redis
支持对指定键添加过期事件,当超过指定时间后,会自动删除如下(单位时间为秒)expire key3 100
此方法会返回受响应的键的数量,我们可以通过
ttl
命令来查询当前键的剩余过期时间,如下ttl key3
返回字段为剩余时间,它有两种特殊的返回
- 如果返回-1,证明当前查询的键没有设置过期事件
- 如果返回-2,则证明当前的键不存在
-
6 ,值的数据结构类型
我们可以通过
type
命令来查询指定键的对应值的数据类型如:type key3
我们将得到返回值的基本数据类型
string
(您不进行覆盖操作的前提下)
数据结构和内部编码
如上type
指令返回的就是当前值的基本数据类型。基本数据类型分别是 string
(字符串)、hash
(哈希)、list
(列表)、set
(集合)、zset
(有序集合),但这些仅仅是 Redis
对外的数据结构,如下图。
如图所示,这样设计的好处
-
1.可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令。
-
2.多重内部编码实现可以在不同场景下发挥各自的优势,例如
zipList
比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis
会根据配置选项将列表类型的内部实现转换为linkedList
。
单线程架构
Redis
使用了单线程架构和I/O
多路复用模型,来实现高性能的内存数据库服务。本节简单介绍一下Redis
的单线程命令处理机制,接着简单分析一下Redis
单线程模型为什么性能如果之高,最终您会对Redis
的单线程模型有初步的了解。
-
一.单线程处理机制
Redis
是单线程来处理命令的,所以一条命令从客户端到达服务端,会进入一个队列中,然后逐个执行,不会存在两条指令同时执行的情况,如图:
-
二.为什么单线程还能这么快。
-
1,纯内存访问,
Redis
将所有数据都放在内存中,内存的响应时长大约为100纳秒 这是 Redis 达到每秒百万级的重要基础 -
2,非阻塞 IO ,
Redis
使用epoll
作为I/O
多路复用技术的实现,再加上Redis
本身的时间处理模型将epoll
中的连接,读写,关闭都转换为事件,不在网络I/O
上浪费过多的时间 -
3,单线程避免了线程切换和竞态产生的消耗。
*单线程可以简化数据结构和算法的实现,其次避免了线程切换和竞态产生的消耗。但是单线程对于每个命令的执行时间是有要求的,如果某个指令执行时间过长的话,会造成其他命令的阻塞,对于
Redis
这种高性能的服务是致命的,所以Redis
是面向快速执行场景的数据库。
-