Redis简述

认识Redis:

Redis是一种基于键值对(key-value)的NoSQL数据库,不像memcache只支持单一数据结构

Redis提供了多种数据结构: string(字符串)、hash(哈希)、List(列表)、set(集合)、zset(有序集合)

除此之外,在string的基础上扩展了 Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)

Redis提供了RDB和AOF机制进行数据持久化,在断电或者机器故障的情况下,保证数据"不丢失"

除此之外,还提供了发布订阅、Lua脚本、键过期等附加功能

更重要的一点就是,Redis特别快(官方给的数字是读写每秒10w)

总之,Redis强大到就像一把瑞士军刀,很多场景都可以使用Redis

 

Redis快的原因:

> redis是基于内存的,内存的读写速度非常快

> Redis是C语言开发的,一版来说C语言实现的程序 "距离" 操作系统更近,执行速度更快

> redis是单线程的,省去了很多上下文切换线程和抢占锁的时间

> redis使用多路复用技术,可以处理并发的连接。非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。

epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间

客户端通信协议:

* 客户端和服务端的通信是基于TCP

* Redis制定了RESP(Redis序列化协议),这种协议简单高效,即能被机器识别,又容易被人类识别

* 例如:

客户端发送 set hello redis ,按照RESP的标准,客户端就会把它封装成如下格式

*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n

\r\n表示回车换行的意思,我们手动把它换行一下:

*3
$3
SET
$5
hello
$5
world

这就是客户端执行的 set hello redis 命令

服务端回复 : +OK


* Redis返回结果其实是有多种类型的:

状态回复:在RESP中,第一个字节为 "+"

错误回复:在RESP中,第一个字节为 "-"

整数回复:在RESP中,第一个字节为 ":"

字符串回复:在RESP中,第一个字节为 "$"

多个字符串回复:在RESP中,第一个字节为 "*"


注: JAVA客户端Jedis就是基于RESP协议(在TCP协议的基础上构建的)

为什么Redis使用单线程

1.不需要各种锁的性能消耗

Redis的数据结构并不全是简单的Key-Value,还有list,hash等复杂的结构,这些结构有可能会进行很细粒度的操作,

比如在很长的列表后面添加一个元素,在hash当中添加或者删除一个对象。

这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加。

总之,在单线程的情况下,就不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

2.减少CPU消耗

采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。


Redis单线程的优劣势

优势:

代码更清晰,处理逻辑更简单

不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗

不存在多进程或者多线程导致的切换而消耗CPU

劣势:

无法发挥多核CPU性能(因为是单线程,所以一个核就可以满足了,如果服务器是多核CPU,显然不能发挥多核的优势)

弥补方式:可以通过在单机开多个Redis实例来完善(每个核对应一个Redis实例,具体要做成集群还是多个单实例,根据自己公司业务决定)

猜你喜欢

转载自www.cnblogs.com/weishao-lsv/p/12942068.html