1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Redis数据库在分布式缓存中的应用研究

Redis数据库在分布式缓存中的应用研究

时间:2021-01-15 08:48:23

相关推荐

Redis数据库在分布式缓存中的应用研究

本文主要讲解用Redis数据库作为分布式缓存。

目录

1.Redis简介

2.Redis应用场景

1.缓存

2.队列

3.单点登录

3.安装Redis

(1)下载Redis

(2)启动Redis

(3)下载Redis管理工具Redis Desktop Manager

4.配置Redis

5.Redis类型

(1) string(字符串)

(2) hash(哈希)

(3) list(列表)

(4) set(集合)

(5) zset(sorted set, 有序集合)

小结:Redis类型的应用场景

6.Redis命令

(1) key(键)

(2) string(字符串)

(3) hash(哈希)

(4) list(列表)

(5) set(集合)

(6) zset(sorted set, 有序集合)

7.在 Core中使用Redis缓存Session

(1) 安装StackExchange.Redis

(2) 安装Microsoft.Extensions.Caching.Redis

(3) 配置Redis连接字符串

(4) 配置Redis缓存服务

(5) 测试Redis缓存服务

8.Redis通信协议

(1) 简介

(2) 网络层(Networking layer)

(3) 请求响应模型(Request-Response model)

(4) RESP协议描述(RESP protocol description)

(5) RESP简单字符串(RESP Simple Strings)

(6) RESP错误(RESP Errors)

(7) RESP整数(RESP Integers)

(8) RESP大容量字符串(RESP Bulk Strings)

(9) RESP数组(RESP Arrays)

(10) RESP数组中的空元素(Null elements in RESP Arrays)

(11) 向Redis服务器发送命令(Sending commands to a Redis Server)

(12) 多个命令和管道(Multiple commands and pipelining)

(13) 内联命令(Inline Commands)

(14) 用于Redis协议的高性能解析器(High performance parser for the Redis protocol)

源码

讨论

1.Redis简介

/xgangzai/category_9289426.html

/redis/redis-tutorial.html

https://redis.io/ (官方)

/ (中文)

官方对Redis的介绍如下:

“Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.”

“Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings),散列(hashes),列表(lists), 集合(sets), 有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径查询。 Redis内置了复制(replication),LUA脚本(Lua scripting),LRU驱动事件(LRU eviction),事务(transactions)和不同级别的磁盘持久化(persistence),并通过 Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(high availability)。”

简而言之,Redis是一个开源(BSD许可)的,使用C语言编写,既可以基于内存也可以持久化的一个高性能的Key-Value数据库。相较于其它Key-Value数据库,Redis具备以下优势:

(1) 性能极高

因为是基于字典(Dictionary)的Key-Value数据库,数据存在内存中,存取时间复杂度是O(1),这带来极高的速度,例如微软.NET的数据字典,在内存中读写100万数据大概300毫秒,对于Key-Value数据库来说,性能瓶颈主要发生在对数据进行持久化和原子一致性操作上,Redis读的速度大约是110000次/s,写的速度是81000次/s。

(2) 丰富的数据类型

Redis支持Strings(字符串), Lists(列表), Hashes(哈希), Sets(集合)及Ordered Sets(有序集合)数据类型操作。

(3) 支持事务

Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

(4) 丰富的特性

Redis可用于缓存,消息,通知,Key过期自动删除等。

2.Redis应用场景

1.缓存

后端:

对于分布式微服务架构,常根据模块将服务划分在后端不同的容器中,以WebApi的形式向应用提供服务。

当前端应用需要大量的读写数据的时候,为了避免每次接口请求都要去查询数据库,可以把一些数据缓存到Redis中,这样是直接从内存中获取数据,大幅提高响应速度。

前端:

(1) Session缓存

对于前端应用,用户登陆的一些信息存到Session中,并缓存到Redis中。

Redis根据Session ID设置过期时间以自动删除,保持与Session的生命周期同步。

(2) 购物车缓存

对于前端购物,可将购物车中的商品ID、商品名称、购买数量生成哈希,以用户ID作为Key,

缓存到Redis,这样购物车信息就不会随用户登录退出删除。

(3) Top N List缓存

如果想要根据Cookie中记录的用户信息,或者前端购物应用的用户信息,跟踪用户最近常访问的商品以判断其个人喜好;或者统计站点最热的商品、点击率最高的商品、活跃度最高的用户等等。如果将这些数据频繁地写入关系数据库,将给数据库带来极大的压力。可以构造一个列表,以用户ID作为Key,缓存到Redis。

2.队列

Redis中提供了list接口,这个list提供了lpush和rpop,这两个方法具有原子性,可以插入队列元素和弹出队列元素。参考:.cn/order/3584.html。

在排队系统中,例如用户购票、大厅排队,如果想要限定用户的次序,采用先进先出的原则,那么采用Redis队列属性和lpush lpop两个函数即可解决。

3.单点登录

同一用户在多端(例如手机、平板、电脑等设备)多浏览器(例如IE、Firefox、Google Chrome等)中发起会话的时候,为了只允许用户单点登录系统,此时可以采用Redis限制用户。例如:

多用户单账号系统(一个用户只有一个账号,用户即账号):

这种系统中,处理单点登录的规则有两种:

(1)如果用户已经登录,则在其它设备上登录时不允许登录。

(2)如果用户已经登录,则在其它设备上登录时,提醒是否允许登录当前用户,让用户在其它设备下线,例如QQ即采用这种登录模式。此时,在当前设备登录的时候,将活动的会话ID替换即可,使得其它正在线上的设备因为在Redis中找不到了其活动的会话ID,从而清理当前会话数据后退出。

多用户多账号系统(一个用户有多个账号):

这种系统中,处理单点登录的规则同样有两种:

(1)如果用户的某个账号已经登录,则在其它设备上登录时不允许再用此账号登录。

(2)如果用户的某个账号已经登录,则在其它设备上登录时,提醒是否允许登录当前账号,让用户的其它活动账号在其它设备下线。此时,在当前设备登录的时候,将其它账号的活动会话ID清除即可,使得其它正在线上的设备因为在Redis中找不到了其活动的会话ID,从而清理当前会话数据后退出。

注意:

(1)客户端每次登录的时候除了在Redis中记录当前活动的会话ID以外,还要同步会话超时时间,以保持与客户端的会话超时时间一致,这样当超时以后使得Redis能自动清理用户登录信息,防止垃圾数据出现。

(2)在分布式微服务架构中,客户端应用可能部署在多个容器中,因此用户的会话数据应缓存到中心数据库中,这样才能起到单点登录控制目的。

3.安装Redis

(1)下载Redis

Windows版本:/microsoftarchive/redis/releases。

Linux版本:http://redis.io/download

本文下载的是Windows版本的Redis

(2)启动Redis

修改启动配置文件redis.windows.conf查找“requirepass”去掉注释符“#”,启用连接时要求密码:

编写一个批处理文件,输入:

另存为“RedisStartup.bat”,然后双击启动Redis服务器,启动后如下,默认监听6379端口以接受客户端连接:

(3)下载Redis管理工具Redis Desktop Manager

工具名称:Redis Desktop Manager

下载地址:/

源码地址:/uglide/RedisDesktopManager

下载完成后,启动“Redis Desktop Manager”新建一个连接,连接名称任意设置,如下:

注意前面在配置文件中设置的连接密码:clouderpwebappcache 单击“OK”后:

Redis为我们提供了15个数据库,我们可以在任意数据库中读写数据。

Redis数据库安装完成。

4.配置Redis

在Redis所在目录中新建一批处理文件,输入:

另存为“RedisConnection.bat”,然后双击连接到Redis服务器,连接后如下:

现在已经连接到Redis服务器,可以对数据库进行操作了,例如输入命令config get * 查看所有配置项目:

Redis提供的配置项默认清单如下:

上表的每个配置项的说明参见“redis.windows.conf”配置文件中的描述。

可以通过config set命令修改配置项,例如:

常用的重要配置项如下表所示:

5.Redis类型

Redis支持五种数据类型:

string(字符串)

hash(哈希)

list(列表)

set(集合)

zset(sorted set, 有序集合)

(1)string(字符串)

string是redis最基本的类型。string类型是二进制安全的,意思是redis的string可以包含任何数据,例如jpg图片或者序列化的对象。string类型的值最大能存储512MB,这意味着你可以将任何序列化对象以字符串形式存储,例如Json字符串,这在缓存数据时非常有用。

命令:

(2)hash(哈希)

hash是一个键值对(key-value)集合,即数据字典。hash特别适合用于存储对象。每个hash可以存储232 -1键值对,即一个集合的元素数量可以多达40多亿。

在上例中创建了一个名为organization的哈希,其key-value对是一个Organization模型的成员。由此我们可以看出hash适合用来存储对象。命令:

(3)list(列表)

list是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(lpush)或者尾部(rpush)。列表最多可存储232 – 1个元素(4294967295,每个列表可存储40多亿)。

命令:

(4)set(集合)

set是string类型的无序集合。集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O(1)。集合中最大的成员数为232-1(4294967295,每个集合可存储40多亿个成员)。

命令:

注意:根据集合内元素的唯一性,相同值反复插入时后面的值会被忽略。

(5)zset(sorted set,有序集合)

zset和set一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis是通过分数来为集合中的成员进行从小到大排序的。zset的成员是唯一的,但分数(score)却可以重复。有序集合中最大的成员数为232-1(4294967295,每个有序集合可存储40多亿个成员)。

命令:

注意:根据集合内元素的唯一性,相同值反复插入时后面的值会被忽略。

小结:Redis类型的应用场景

6.Redis命令

Redis命令用于在Redis服务器上执行操作,以管理数据库中的而对象。

更多命令请参考:https://redis.io/commands

(1)key()

(2)string(字符串)

(3)hash(哈希)

(4)list(列表)

(5)set(集合)

(6)zset(sorted set,有序集合)

7.Core中使用Redis缓存Session

(1)安装StackExchange.Redis

在NuGet包管理中输入:StackExchange.Redis,如下图所示:

源码路径:/StackExchange/StackExchange.Redis/

(2)安装Microsoft.Extensions.Caching.Redis

在NuGet包管理中输入:Microsoft.Extensions.Caching.Redis,如下图所示:

源码路径:/aspnet/Extensions/tree/9bc79b2f25a3724376d7af19617c33749a30ea3a

注意:从Microsoft.Extensions.Caching.Redis 2.2.0开始,

微软已经正式将其更名为:Microsoft.Extensions.Caching.StackExchangeRedis

在NuGet包管理中输入:Microsoft.Extensions.Caching.StackExchangeRedis,如下图所示:

源码路径:/aspnet/Extensions/tree/9bc79b2f25a3724376d7af19617c33749a30ea3a

注意:同为2.2.0版本

Microsoft.Extensions.Caching.Redis和

Microsoft.Extensions.Caching.StackExchangeRedis

的依赖项目完全不一样

Microsoft.Extensions.Caching.Redis 依赖StackExchange.Redis.StrongName (>= 1.2.6)

Microsoft.Extensions.Caching.StackExchangeRedis 依赖 StackExchange.Redis (>= 2.0.513)

这说明从2.2.0开始StackExchangeRedis正式命名为:StackExchange.Redis

而微软也正式和StackExchangeRedis保持一致,因此应该选择:

Microsoft.Extensions.Caching.StackExchangeRedis

下载并安装完成后如下:

(3)配置Redis连接字符串

打开appsettings.json文件,增加Redis数据库连接串:

(4)配置Redis缓存服务

在Startup.cs文件的的ConfigureServices(IServiceCollection services)中增加Redis缓存服务:

(5)测试Redis缓存服务

在HomeController控制器的中输入:

确保Redis服务器正在运行中:

以调试模式启动App:

此时用Redis Desktop Manager打开Redis我们会看到会话已经缓存到Redis中:

此时我们注意到缓存的会话Key的过期时间是30秒,和Session的超时时间一致:

现在把Session在无响应的情况下的过期时间改成1小时,后重新启动App:

说明Redis缓存的会话的过期时间和客户端的实际的会话过期时间是保持一致的(注意:误差几秒是因我查看不及时的原因)。

过一段时间以后,查看Redis中会话的TLL:

现在在浏览器中按F5刷新一下页面,让会话处于活动状态,再看Redis中会话的TLL:

此时我们看到TTL又恢复到了3600秒,说明刷新页面的时候客户端同步了Redis中会话的TTL。

现在验证在后端缓存断开的情况下会不会抛出异常。

关闭Redis服务器,然后在浏览器中按F5刷新页面:

没有抛出错误,但是会话ID已经不存在,出现异常:

结论:采用数据库缓存会话的风险在于,一旦数据库关闭或崩溃就会导致当前会话无效,同时每刷新一次页面都会连接数据库,如果连接时间超时时间是30秒,则页面要等待30秒连接失败以后才能显示出来,这是不可接受的。

8.Redis通信协议

参考: https://redis.io/topics/protocol (官方)

(1)简介

Redis客户端使用一种称为RESP协议(REdis Serialization Protocol,Redis序列化协议)与Redis服务器通信。虽然该协议是专门为Redis设计的,但它可以用于其他客户机-服务器(client-server)软件项目。

RESP协议主要是从以下方面进行考虑后设计的结果:

ESP可以序列化不同的数据类型,例如整数(integers)、字符串(strings)、数组(arrays),还有一个特定的错误(errors)类型。请求以字符串数组(arrays of strings)的形式从客户端发送到Redis服务器,这些字符串表示要执行的命令和参数。Redis使用特定于命令的数据类型(command-specific data type)进行响应。

RESP是二进制安全的(binary-safe)(这意味着可以传输二进制数据),不需要处理从一个进程传输到另一个进程的批量数据(bulk data),因为它使用前缀长度(prefixed-length)来传输批量数据(bulk data)。

注意:这里列出的协议仅用于客户机-服务器通信(client-server communication)。Redis集群(Redis Cluster)使用不同的二进制协议(binary protocol)在节点之间交换消息。

(2)网络层(Networking layer)

客户端连接到Redis服务器,在6379端口上创建TCP连接(以用于传输数据到服务器)。

虽然RESP在技术上不特定于TCP,但在Redis上下文中,该协议仅用于TCP连接(或类似Unix sockets的面向流的连接)。

(3)请求响应模型(Request-Response model)

Redis接受由不同参数(arguments)组成的命令(commands)。服务器接收到命令后,将对其进行处理并将应答(reply)发送回客户端。

这是最简单的模型,但有两个例外:

(1)Redis支持管道(pipele)操作(本文档后面将介绍)。因此,客户端可以同时发送多个命令(multiple commands),然后等待稍后的回复。

(2)当Redis客户端订阅了发布/订阅频道(Pub/Sub channel),协议语义变化,成为推动协议(pushprotocol),也就是说,客户不再需要发送命令,因为服务器会自动发送新消息到客户端。

排除上述两个例外,Redis协议是一个简单的请求-响应协议(request-response protocol)。

(4)RESP协议描述(RESP protocol description)

RESP协议在Redis 1.2中引入,但在Redis 2.0中成为与Redis服务器通信的标准方式。这是你应该在你的Redis客户端实现的协议(也就是说要与Redis服务器通信数据必须采用RESP协议)。

RESP实际上是一个序列化协议(serialization protocol),它支持以下数据类型(data types):

RESP在Redis中用作请求-响应协议(request-response protocol)的方式如下:

(1)客户端请求(request):客户端将命令封装成由大容量字符串组成的RESP数组(RESP Array of Bulk Strings)发送到Redis服务器(也就是说客户端发送的是一个数组,数组的内容是由大容量字符串组成的二进制数据)

(2)服务器响应(response):服务器根据收到的命令(command)采用不同的RESP类型进行响应。在RESP中,某些数据的响应类型取决于第一个字节:

此外,RESP还可以使用稍后指定的特殊大容量字符串(Bulk Strings)或数组(Array)变体来表示空值(Null)。在RESP中,协议的不同部分总是用"\r\n"(CRLF)终止(terminated)。

(5)RESP简单字符串(RESP Simple Strings)

简单字符串的编码方式如下:

简单字符串用于传输开销最小的非二进制安全字符串。例如,许多Redis命令回复成功时只有"OK",作为一个RESP简单字符串编码为以下5个字节:

为了发送二进制安全(binary-safe)的字符串,请使用RESP大容量字符串(Bulk Strings)替代。

当Redis使用一个简单的字符串进行应答时,客户端应该向调用者返回"+"后面的字符串,不包括最后的CRLF字符。

(6)RESP错误(RESP Errors)

RESP为错误设计了一个特定的数据类型。实际上,错误与RESP简单字符串完全相同,但是第一个字符是"-"字符,而不是"+"字符。

简单字符串和RESP中的错误之间的真正区别是,客户端将错误视为异常。它的基本格式为:

错误回复只在发生错误时发送,例如当您试图对错误的数据类型执行操作时,或者当命令不存在时,等等。当接收到错误回复时,客户端应引发异常。下面是错误回复的例子:

"-"后面的第一个单词,直到第一个空格或换行,表示返回的错误类型。这只是Redis使用的约定,不属于RESP错误格式的一部分。

例如,ERR是通用错误,而WRONGTYPE是更具体的错误,它表示客户端试图对错误的数据类型执行操作。这称为错误前缀(Error Prefix)允许客户端理解服务器返回的错误类型,而不需要依赖于所给出的确切消息,因为消息可能会随着时间的推移而变化。

客户端可以根据不同的错误返回不同类型的异常,或者直接将错误消息作为字符串提供给调用者来提供捕获错误的通用方法。

但是,这样的特性不应该被认为是至关重要的,因为它很少有用,而且有限的客户端实现可能只返回一般的错误条件,例如false。

(7)RESP整数(RESP Integers)

整数类型只是一个以CRLF结尾的字符串,表示一个整数,前面有一个":"字符。例如,":0\r\n"或":1000\r\n"是整数。整数的编码方式如下:

许多Redis命令返回RESP整数,例如INCR, LLEN 和 LASTSAVE。

对于返回的整数没有特殊意义,它只是代表INCR命令的一个增量数,LASTSAVE命令的一个UNIX时间,等等。但是,返回的整数保证在有符号的64位整数范围内(a signed 64 bit integer)。

整数应答也广泛用于返回真或假。例如,EXISTS或SISMEMBER之类的命令将返回1表示真,0表示假。其他命令,如SADD、SREM和SETNX,如果实际执行了操作,则返回1,否则返回0。

以下命令将以整数应答: SETNX, DEL, EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTSAVE, RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD.

(8)RESP大容量字符串(RESP Bulk Strings)

大容量字符串用于表示单个二进制安全字符串,长度不超过512MB。 (二进制安全是指不对任何字节进行特殊标识、转码等,也就是按字节处理,原样输出)。

大容量字符串的编码方式如下:

因此字符串"foobar"被编码如下:

一个空字符串(empty string)时:

大容量字符串也可以使用表示空值的特殊格式来表示值不存在。在这种特殊的格式中,长度是-1,没有数据,所以Null表示为:

这称为Null Bulk String。客户端API不应该返回空字符串(empty string),而应该返回nil对象(null对象),当服务器使用Null Bulk String进行应答时。例如,Ruby应该返回'nil',而C应该返回NULL,C#应返回null等等。

(9)RESP数组(RESP Arrays)

这里再次强调,客户端使用RESP数组向Redis服务器发送命令。

类似地,某些使用RESP数组向客户端返回元素集合的Redis命令是应答类型。一个例子是返回列表元素的LRANGE命令。

RESP数组使用以下格式发送数据给服务器:

所以,空数组是这样的:

例如,当数组的元素由2两个RESP Bulk Strings :"foo"和"bar"组成的时候,数组被编码为:

可以看到,在*<count>CRLF部分为数组加上前缀之后,后面组成数组元素的其他RESP类型只是一个接一个地连接起来。例如,一个有三个整数的数组编码如下:

因此数组的元素可以包含混合类型(mixed types),即元素不必具有相同的RESP类型。例如,一个包含四个整数和一个大容量字符串的列表可以编码如下:

(为了清晰起见,回复也被分成了几行)

服务器发送的第一行是*5\r\n,以便指定接下来的5个响应。然后,发送构成多个批量应答项(Multi Bulk reply)的每个应答。

空数组(Null Array)的概念也存在,它是指定空值的另一种方法(通常使用Null Bulk String,但由于历史原因,我们有两种格式)。

例如,当BLPOP命令超时时,它返回一个空数组,其计数为-1,如下例所示:

当Redis返回一个空数组时,客户端API应该返回一个空对象(null object),而不是一个空数组(Null Array)。这对于区分空列表和不同的条件(例如BLPOP命令的超时条件)是必要的。

在RESP中可以使用数组的数组(即数组中包含数组)。例如,两个数组的数组编码如下:

(为了便于阅读,该格式也被分成了多行).

上面的RESP数据类型编码一个双元素数组,该数组包含三个整数1、2、3和一个由简单字符串和错误构成的数组。

(10)RESP数组中的空元素(Null elements in RESP Arrays)

数组的单个元素可以为空(Null)。这在Redis的回复中使用,以表明这些元素是缺失的,而不是空字符串(empty strings)。当与GET模式(GET pattern)选项一起使用时,当指定的键丢失时,排序命令可能会发生这种情况。一个数组回复包含一个空元素的例子:

第二个元素是Null。客户端应该返回如下内容:

注意,这并不是前面几节中提到的一个例外,只是一个进一步指定协议的示例。

(11)Redis服务器发送命令(Sending commands to a Redis Server)

现在您已经熟悉了RESP序列化格式(RESP serialization format),编写一个Redis客户端库的实现将会很容易。这对你用编程语言(例如C/C++/C#/Java等)实现一个Redis客户端至关重要。现在进一步强调客户端和服务器之间的交互是如何工作的:

例如,一个典型的相互交互是这样的:

客户端发送命令LLEN mylist,以获得存储在mylist中的列表长度,服务器使用整数应答,如下面的示例所示(C:是客户端,S:服务器)。

为了简单起见,我们通常用换行(newlines)来分隔协议的不同部分,但是实际的交互是客户端将*2\r\n$4\r\nLLEN\r\n$6\r\nmylist\r\n作为一个整体发送给服务器。

(12)多个命令和管道(Multiple commands and pipelining)

客户端可以使用相同的连接来发出多个命令(multiple commands)。

Redis支持管道(即流水线作业),因此客户端可以通过一个写操作发送多个命令,而不需要在发出下一个命令之前读取上一个命令的服务器应答。所有的回复都可以在最后看到。

有关更多信息,请查看我们关于管道的页面:about Pipelining。

(13)内联命令(Inline Commands)

有时你只有telnet在手,你需要发送一个命令到Redis服务器。虽然Redis协议易于实现,但在交互式会话中使用它并不理想,而且Redis-cli可能并不总是可用。出于这个原因,Redis还以一种专门为人类设计的方式接受命令,这种方式被称为内联命令(inline command)。简单地说内联命令就是直接命令,只需要在终端输入Redis支持的命令即能和服务器进行交互通信。

下面是一个使用内联命令的服务器/客户端聊天示例(S:代表服务器,C:代表客户端)

下面是另一个内联命令返回整数的例子:

基本上,您只需在telnet会话中编写空格分隔的参数。由于没有在统一请求协议中使用以*开头的命令,所以Redis能够检测此条件并解析您的命令。

(14)用于Redis协议的高性能解析器(High performance parser for the Redis protocol)

虽然Redis协议非常易于阅读和实现,但它的实现性能类似于二进制协议。

RESP使用带前缀的长度(prefixed lengths)来传输大量数据(transfer bulk data),因此不需要扫描负载(payload)以查找特殊字符(例如JSON),也不需要引用需要发送到服务器的负载。

对于Bulk和Multi Bulk length,可以使用代码进行处理,每个字符执行一个操作,同时扫描CR字符,如下所示的C代码,读取字符串的长度:

识别出第一个CR后,可以与下面的LF一起跳过,而不进行任何处理。然后,可以使用不以任何方式检查有效负载的单个读操作读取批量数据。最后,将剩余的CR和LF字符丢弃,不进行任何处理。

虽然Redis协议在性能上可以与二进制协议相媲美,但在大多数非常高级的语言中实现起来却要简单得多,从而减少了客户端软件中的bug。

源码

本文仅源码参列出Redis客户端框架,详细实现源码参见: /bzmework/FastCore

讨论

欢迎加入QQ群讨论交流:948127686。本群专注于.NET技术的研究和讨论。

错误之处在所难免,欢迎批评和指正!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。