Redis认识常用数据结构(一)

文章目录

  • 1.Redis里面的数据类型
  • 2.指令查询验证
  • 3.redis单线程模型
  • 4.Redis里面的string类型
  • 5.String内部的编码方式

1.Redis里面的数据类型

1) 下面的这个就是我们的redis里面的数据类型和对应的可能用的内部编码:
image-20241129214321047
2) 例如这个string:就是我们承诺这个数据类型是string,但是这个实际上使用的是哪一个编码方式,是这个raw还是另外的两个,都是我们的redis根据这个实际情况进行灵活的调整的;
3) 这个里面的hashtable和我们的这个java里面学习的HashTable是不一样的,这个里面的是redis自己的;
4) zip表示的就是压缩的意思,具体到这个里面就是我们的压缩链表,这个是为了节省空间(当数据量很小的时候);
5) skiplist表示的就是我们的跳表,就是在我们的这个链表的基础上面,添加随机的指针,指向这个链表里面的其他的节点,这个时候可以加快我们的这个查询的效率;

2.指令查询验证

下面的这个就是使用我们的这个指令查看这个具体的内部编码方式:

具体解释一下就是:我们的这个key1的数据类型是string类型的,但是具体到这个内部就是按照这个int进行处理的,这个就是redis内部的处理;

image-20241129215205586

3.redis单线程模型

Redis使用一个线程处理所有的请求,并不是这个过程只涉及到了一个线程,而是其他的线程负责处理这个网络IO的相关的内容,执行的结果还是交给我们的这个主线程进行处理的;

Redis是单线程模型,但是为什么这么快呢?

1)这个所谓的快:主要是和其他的关系型数据库进行比较的;

2)Redis访问内存;

3)Redis做的这个核心的业务比我们的这个数据库要做的事情更加简单;

4)单线程模型:避免了多线程里面的这个竞争的开销(操作是短平快,不会消耗大量的CPU);

5)Redis处理网络IO的时候,使用的是我们的多路复用的原则(epoll)—一个线程管理多个socket;

一个服务器服务多个客户端,这个时候会有多个socket,但是这些socket并不是每时每刻都在传输数据,即同一时刻,只有少量的这个socket又进行数据的传输;

IO多路复用就是在上面的基础上,一个线程处理多个socket;

epoll就是事件的通知机制(一个线程负责的多个socket需要执行的时候,就会通知我们的线程执行,前提是这个里面的socket交互不是很频繁);

4.Redis里面的string类型

我们的这个Redis里面的key都是字符串类型的,我们讨论的这个数据类型都是针对于这个value而言的,key的类型都是一样的;

Redis里面对于这个string的大小进行了限制,保证每一次的这个操作的速度是很快的;

1) 为了防止之前的相关的键值对于我们的后续操作的影响,这个时候我们可以执行下面的这个操作flushall就是清空之前的内容;
image-20241130134513819
2) 下面的这个就是组合设计set和expire(过期时间)指令
image-20241130134621510
3) 下面我们介绍一下这个xx和nx的用法:
为了帮助大家进行理解,我直接使用下面的这个案例进行说明;
我们的这个客户端上面仅仅存在这个key1这个内容,这个时候我们使用xx进行设置:
这个表示的就是存在的时候才可以设置,因为我们的这个key2是不存在的,因此这个是用加上xx的set就是无效的,因此这个显示的结果就是nil数值;
nx表示的就是不存在就设置(n就是not的意思)因此我们使用这个set ----nx设置这个key2的时候就会成功,因为这个时候的key2是不存在的;
key2存在之后,我么使用这个xx进行设置,这个时候就会生效的;
image-20241130134753584
4) 我们的这个get查询的时候只能查询这个string字符串类型的,对于其他的类型就会报错(当然有其他的手段),下面的这个就是查询这个lsit类型的报错情况;
image-20241130135137224
5) mget和mset的使用
一次性设置多个和一次性获取多个,可以提高我们的效率,因为我们的这个Redis的客户端和服务器是通过网络进行通信的,一次性进行多个查询可以提高这个速度;
image-20241130135741317
下面的这个就是对于上面解释的一个图解说明:
image-20241130140238776
6) setnx和setex和psetex
setnx就是不存在才可以设置,和上面的就是一样的,只不过上面的是需要额外的跟在后面,我们这个地方直接进行了简化;
这个setex和上面的setnx同理,也就是一个简化;
psetex和setex的区别就是设置的时间的单位不一样:我们的psetex单位是毫秒,setex单位是秒;
7) 对于数字的相关操作
incr:针对value加上1;
incrby:针对value加n;
decr:针对value减1;
decrby:针对value加上n;
incrbyfloat:这个value加上小数操作;
8) 客户端工具演示
image-20241201195121300
key3是一个浮点数,我们的incr无法直接操作,key6不存在,我么使用这个incr,这个时候就会进行创建这个key并且加上1;其他的这个incr对于int操作就是我们理解的(没有什么需要注意的);
image-20241201195620268
上面的这个是incebyfloat对于浮点数的操作,很容易理解;
9) append的使用
字符串在这个utf8编码下面,一个汉字就是3个字节
image-20241201200920773
添加的汉字是以16进制的方式进行展示的,因为这个编码的方式问题,我们的两个汉字就是6个字节
但是这个16进制不是很直观,不方便我们在这个客户端上面进行查看:
这个时候我们可以使用这个redis-cli --raw重进这个客户端,这个时候就会显示我们的汉字而不是16进制,方便我们进行查看;
我们如何退出这个客户端:难道是点击叉号吗??肯定不是啦,使用的是ctrl+D快捷键,这个时候就会退出;
顺便说一下,这个不要轻易使用这个ctrl+s快捷键,这个和我们的ctrl+D挨得比较近,但是这个表示冻结,按下这个我们的linux就会无法操作了,这个主要是查看日志的,因为我们的这个日志量很多的时候我们想要查看某一个部分,这个时候使用这个快捷键的;
如果我们的这个不小心误操作ctrl+s,可以使用这个ctrl+s取消这个锁定的操作,就恢复了,你记住了吗~~~
10) getrange的用法:获取这个字符串里面的指定的范围的某一部分
我们的这个获取的区间设置参数的时候都是闭区间,不会出现是开区间的情况;
image-20241201201203030
下面的这个证明,我们的这个参数是支持负数,这个-1表示的就是倒数第一个字符,以此类推;
image-20241201201326494
11) setrange对于这个切割的字符串进行修改
setrange key offset value 这个offset就是偏移量,根据我们的value的大小确定修改的字符的个数;
image-20241201201711070
12) strlen获取字符串的长度
image-20241201202516071

5.String内部的编码方式

我们的这个string的编码方式,主要是三种:

1)raw:表示的就是普通的字符串;

2)embstr:压缩字符串,适合表示比较短的字符串;

3)int:这个就是64位/8字节的整数;

image-20241201203427196

Redis对于整数和小数的处理:

我们的Redis对于整数进行的存储,进行相关的运算是很高效的,但是对于小数而言,就有些差强人意了,这个主要是因为我们的这个Redis里面是把这个小数作为字符串进行处理的;

我们对于这个Redis里面的小数进行操作的时候,先转换为这个字符串,然后进行小数的运算,运算之后把这个结果再次转换为我们的小数,这个转换的过程肯定是有开销的;
要是因为我们的这个Redis里面是把这个小数作为字符串进行处理的;

我们对于这个Redis里面的小数进行操作的时候,先转换为这个字符串,然后进行小数的运算,运算之后把这个结果再次转换为我们的小数,这个转换的过程肯定是有开销的;

上一篇:c#派生类Manager,Salesman创建


下一篇:rpc设计的再次思考20251215(以xdb为核心构建游戏框架)