加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

Streams:一个新的Redis通用数据布局

发布时间:2018-08-18 02:23:42 所属栏目:编程 来源:Antirez
导读:技能沙龙 | 邀您于8月25日与国美/AWS/转转三位专家配合切磋小措施电商拭魅战 直到几个月早年,对付我来说,在动静转达的情形中, 流 streams 只是一个风趣且相对简朴的观念。这个观念在 Kafka 风行之后,我首要研究它们在 Disque 案例中的应用,Disque 是一个
副问题[/!--empirenews.page--] 技能沙龙 | 邀您于8月25日与国美/AWS/转转三位专家配合切磋小措施电商拭魅战

Streams:一个新的Redis通用数据布局

直到几个月早年,对付我来说,在动静转达的情形中,streams只是一个风趣且相对简朴的观念。这个观念在 Kafka 风行之后,我首要研究它们在 Disque 案例中的应用,Disque 是一个动静行列,它将在 Redis 4.2 中被转换为 Redis 的一个模块。其后我抉择让 Disque 都用 AP 动静(LCTT 译注:拜见 CAP 定理),也就是说,它将在不必要客户端过多参加的环境下实现容错和可用性,这样一来,我越发确定地以为流的观念在那种环境下并不合用。

然而在当时 Redis 有个题目,那就是缺省环境下导出数据布局并不轻松。它在 Redis 列表list有序集sorted list宣布/订阅Pub/Sub成果之间有某些缺陷。你可以衡量行使这些器材对一系列动静或变乱建模。

有序集是内存耗损大户,那天然就不能对投递的沟通动静举办一次又一次的建模,客户端不能阻塞新动静。由于有序集并不是一个序列化的数据布局,它是一个元素可以按照它们量的变革而移动的荟萃:以是它不像时序性的数据那样。

列表有其它的题目,它在某些特定的用例中会发生相同的合用性题目:你无法赏识列表中间的内容,由于在那种环境下,会见时刻是线性的。另外,没有任何指定输出的成果,列表上的阻塞操纵仅为单个客户端提供单个元素。列表中没有牢靠的元素标识,也就是说,不能指定从哪个元素开始给我提供内容。

对付一对多的事变使命,有宣布/订阅机制,它在大大都环境下长短常好的,可是,对付某些不想“即发即弃”fire-and-forget的对象:保存一个汗青是很重要的,不可是由于是断开之后会从头得到动静,也由于某些如时序性的动静列表,用范畴查询赏识长短常重要的:好比在这 10 秒范畴内温度读数是几多?

我试图办理上述题目,我想筹齐整个通用的有序荟萃,并列入一个奇异的、更机动的数据布局,然而,我的计划实行最终以天生一个比当前的数据布局越发装腔作势的功效而了却。Redis 有个甜头,它的数据布局导出更像天然的计较机科学的数据布局,而不是 “Salvatore 发现的 API”。因此,我最终遏制了我的实行,而且说,“ok,这是我们今朝能提供的”,或者我会为宣布/订阅增进一些汗青信息,可能为列表会见增进一些更机动的方法。然而,每次在集会会议上有效户对我说 “你如安在 Redis 中模仿时刻系列” 可能相同的题目时,我的脸就绿了。

发源

在 Redis 4.0 中引入模块之后,用户开始思量他们本身怎么去修复这些题目。个中一个用户 Timothy Downs 通过 IRC 和我说道:

  1. <forkfork> 我打算给这个模块增进一个事宜日记式的数据范例 —— 这意味着大量的订阅者可以在不导致 redis 内存激增的环境下做一些像宣布/订阅那样的工作
  2. <forkfork> 订阅者持有他们在动静行列中的位置,而不是让 Redis 必需维护每个斲丧者的位置和为每个订阅者复制动静

他的思绪开导了我。我想了几天,而且意识到这也许是我们顿时同时办理上面全部题目的契机。我必要去从头构想 “日记” 的观念是什么。日记是个根基的编程元素,每小我私人都行使过它,由于它只是简朴地以追加模式打开一个文件,并以必然的名目写入数据。然而 Redis 数据布局必需是抽象的。它们在内存中,而且我们行使内存并不是由于我们懒,而是由于行使一些指针,我们可以观念化数据布局并把它们抽象,以使它们挣脱明晰的限定。譬喻,一样平常来说日记有几个题目:偏移不是逻辑化的,而是真实的字节偏移,假如你想要与条目插入的时刻相干的逻辑偏移应该怎么办?我们有范畴查询可用。同样,日记凡是很难举办垃圾接纳:在一个只能举办追加操纵的数据布局中怎么去删除旧的元素?好吧,在我们抱负的日记中,我们只必要说,我想要数字最大的谁人条目,而旧的元素一个也不要,等等。

当我从 Timothy 的设法中受到开导,去实行着写一个类型的时辰,我行使了 Redis 集群中的 radix 树去实现,优化了它内部的某些部门。这为实现一个有用操作空间的日记提供了基本,并且如故有也许在对数时刻logarithmic time内会见范畴。同时,我开始去读关于 Kafka 的流相干的内容以得到其它的灵感,它也很是得当我的计划,最后小心了 Kafka 斲丧组consumer groups的观念,而且再次针对 Redis 举办优化,以合用于 Redis 在内存中行使的环境。然而,该类型仅逗留在纸面上,在一段时刻后我险些把它从新到尾重写了一遍,以便将我与别人接头的所获得的很多提议一路增进到 Redis 进级中。我但愿 Redis 流能成为对付时刻序列有效的特征,而不只是一个常见的变乱和动静类的应用措施。

让我们写一些代码吧

从 Redis 大会返来后,整个炎天我都在实现一个叫 listpack 的库。这个库是 ziplist.c 的继任者,那是一个暗示在单个分派中的字符串元素列表的数据布局。它是一个很黑白凡的序列化名目,其特点在于也可以或许以逆序(从右到左)理会:以便在各类用例中更换 ziplists。

团结 radix 树和 listpacks 的特征,它可以很轻易地去构建一个空间高效的日记,而且照旧可索引的,这意味着应承通过 ID 和时刻举办随机遇见。自从这些停当后,我开始去写一些代码以实现流数据布局。我还在完成这个实现,不管奈何,此刻在 Github 上的 Redis 的 streams 分支里它已经可以跑起来了。我并没有声称谁人 API 是 100% 的最终版本,可是,这有两个故意思的究竟:一,在当时只有斲丧群组是缺失的,加上一些不太重要的操纵流的呼吁,可是,全部的大的方面都已经实现了。二,一旦各个方面较量不变了之后,我抉择或许用两个月的时刻将全部的流的特征向后移植backport到 4.0 分支。这意味着 Redis 用户想要行使流,不消守候 Redis 4.2 宣布,它们在出产情形顿时就可用了。这是也许的,由于作为一个新的数据布局,险些全部的代码改变都呈此刻新的代码内里。除了阻塞列表操纵之外:该代码被重构了,我们对付流和列表阻塞操纵共享了沟通的代码,而极大地简化了 Redis 内部实现。

教程:接待行使 Redis 的 streams

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读