接上文:深度剖析不一样的Redis架构设计
Posted 二进制跳动
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了接上文:深度剖析不一样的Redis架构设计相关的知识,希望对你有一定的参考价值。
04 Redis高性能设计
Redis是单线程的吗?
Redis的单线程主要是值Redis的网络IO和键值对读写是由一个线程完成的,这也是Reids对外提供键值存储服务的主要流程。但是Redis的其他功能,比如持久化,异步删除,集群数据同步都是由额外的线程执行的。
Redis单线程为什么还能这么快?
每秒的话,差不多可以支持小10万的并发,这已经是一个很恐怖的数据了。
因为他的所有数据都是在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能消耗。正因为Redis是单线的,所有要小心使用Redis的命令。对于那些耗时的命令(比如keys),一定要谨慎。
Redis单线程是如何处理那么多并发客户端的连接?
Redis的IO多路复用:Redis利用Epoll来实现IO多路复用,将连接信息和事件放在队列中,一次放到文件事件分派器,事件分派器将事件分发到事件处理器。
05 Redis核心设计原理
Redi作为key-value存储系统,数据结构如下:(盗图了)
一个Redis实例对应多个DB,一个DB对应多个key,key一般是string的,后面的value是RedisObject,不是说value就是string,list,map这些,而是说这些类型,都被Redis封装成一个叫RedisObject,具体是哪个类型?是用指针的方式来向具体的哪个类型。(盗图了)
RedisBD结构
Redis没有表的概念,Redis实例所对应的DB以编号区分,DB本身就是key的命名空间。比如:user:wengyifei作为key的值,表示在user这个命名空间下id为wengyifei的元素,类似于user表中id=wengyifei的行。
SDS字符串
Redis是用C语言来实现的,在C语言中,String这个类型,其实就是一个char数组,比如char data[] = "xxx\0",但是,客户端往Redis发送set命令,是可以发送任意的字符串的,是没有校验的,所以假如我们发了一个字符串XX\0xx,那么\0后面的xx是不会读的,只会读前面的xx。所以Redis自己实现了一个string叫sds,sds中记录了一个len和一个char buf[],len用来记录buf的长度,比如char buf[] = "xxx\0xx",那么len的长度就是5,sds中还有一个比较重要的属性就是free,表示还剩余多少。free是通过改变len来计算,比如"xxx1234"改成"xxx123456",那么会按照(len+addlen) * 2 =18来扩容,这个时候len就变成了9,free就是18-9也就变成了9。
例如:
char buf[] = 'xxx1234'改成'xxx123456'//这里的buf是柔性数组
free:12 变成 free:10
len:8 变成 len:10
Redis设计SDS字符串有什么好处?
1.二进制安全的数据结构
2.提供了内存预分配机制,避免了频繁的内存分配
3.兼容C语言
4.有单独的统计变量len和free,可以方便的得到字符串长度,这样就避免了读取不完整的风险。
以上是关于接上文:深度剖析不一样的Redis架构设计的主要内容,如果未能解决你的问题,请参考以下文章