Tedis:基于 TiKV 构建的 NoSQL 数据库

2023-11-10 12:20

本文主要是介绍Tedis:基于 TiKV 构建的 NoSQL 数据库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者介绍:
陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计以及饿了么基础架构研发工作。曾任百度架构师,负责百度即时通讯产品的架构设计。具有丰富的大规模系统构 建和基础架构的研发经验,善于复杂业务需求下的大并发、分布式系统设计和持续优化。个人微信公众号 dongming_cdm。

Tedis(https://github.com/eleme/tedis)是基于开源 TiKV 的兼容 Redis 协议的强一致性的 NoSQL 数据库开源项目。 本文介绍一下 Tedis 开源项目的架构设计和特性,以及架构背后的一些思考(包括为何选择 TiKV 和 Redis 协议)。

先来讨论为什么基于 TiKV 构建我们自己的 NoSQL 数据库。

首先简述一下 TiKV[1],TiKV 是 TiDB 的一个子项目,TiDB 是一个分布式的关系型数据库 [2],TiKV 是 TiDB 的存储层。TiKV 本身是可独立于 TiDB 的单独项目。它是一个强一致、可水平扩展的、高可用的分布式 Key-Value 存储系统。

选择 TiKV 的第一个原因是 TiKV 是一个强一致的系统。 在我的另外一篇文章中(发表在 InfoQ, 参看 https://www.infoq.cn/article/rhzs0KI2G*Y2r9PMdeNv ),我阐述了一个观点:NoSQL 数据库应该具有一致性,并且通过多副本技术达到实际的高可用,也就是说 NoSQL 数据库应该是一个“实际上的 CA” (effectively CA)系统。但是在这篇文章中我并没有明确说明 NoSQL 该具有的一致性是哪种一致性。实际上,我所说的一致性其实就是一种强一致性 [3],或者更准确的说是线性一致性 [4]。TiKV 正是具有这种线性一致性。TiKV 中的每个数据都会保存 3 个副本,在只有一个副本的节点宕机或者出现网络分区的情况下,另外 2 个副本仍然能够对外提供服务。理论上来讲,同时出现 2 个以上副本同时坏掉的可能性很小,也就是理论上可以达到非常高的可用性。通过 TiKV 滚动升级等运维辅助,如果在实际的生产中,有良好的运维,可以达到实际上非常高的可用性。也就是称为一个“实际上的 CA”(effectively CA)系统。

TiKV 通过 Raft [5] 协议实现了线性一致性和高可用 2 个特性。Raft 是一种分布式共识协议,通过 Raft 协议,数据可以被认为是原子的写入到 3 个副本上。共识协议的一个特点就是要写入大多数,才会认为写入成功,3 个副本的大多数就是 2 个,也就是在只有一个副本宕机或者网络分区的情况下,仍然可以成功写入,并且提供读服务。

选择 TiKV 的第二个原因是 TiKV 的架构可扩展和生态。 在 TiDB 中 TiKV 是独立的一层,形成了一个很好的可扩展架构,实际上可以在 TiKV 上扩展出很多不同的数据库出来。TiDB 层本身就是这种架构上的一个扩展。这种架构类似于 Google 公司的第一代的 Spanner 系统 [6],Spanner 系统本身也是一个强一致性的、高可用的分布式 Key-Value 系统。在 Spanner 的基础之上,Google 构建了 F1 系统 [7],实现了 SQL 协议。2017 年,Google 升级了 Spanner 到第二代 [8],让 Spanner 本身就具有了 SQL 能力。虽然一代 Spanner+F1 是这样的架构,但它仍然是一种非常优秀的架构。我们的 Tedis 项目,也是构建在这一可扩展架构上的一个项目,依托于 TiKV 提供的底层能力,向上构建了不同于 SQL 协议的 Redis 协议。我相信 TiKV 的这种可扩展架构,未来可以成为一种生态,还可以在上面“⻓出”其他的类型的数据库,比如说 Mango 协议、图协议。这些数据库都具有与底层 TiKV 相同的线性一致性和高可用性,区别只在于对外的接口协议不同。 目前这种生态已初⻅端倪,Titan(https://github.com/distributedio/titan) 这个开源项目,与我们的 Tedis 项目非常类似,他们的开源步伐先于我们,目前做的也非常不错。我相信,我们肯定不是这个生态中的最后一个。

=

总之基于 TiKV,Tedis 实现了以下的技术特性:

1. 大数据量,可以存储至少数十 TB 级别的数据。

2. 高性能,在满足高 QPS 的同时,保证比较低的延时。

3. 高可靠,数据被可靠的持久化存储,少量机器的损坏不会导致数据的丢失。

4. 高可用,作为在线服务的底层依赖存储,要有非常完善的高可用性能力,外卖服务不同于电子商务,对实时性要求非常高,对系统的可用性的要求则是更高的。

5. 易运维,可以在不停服的基础上进行数据迁移和集群扩容。

接下来,我们讨论第二个问题,为什么选择 Redis 协议。

SQL 语言与其背后的关系模型,从 1970s 发明以来,一直在应用开发领域占据这统治地位,虽然在 CAP 定理的推动下 [4],在 NoSQL 运动中,出现很多 NoSQL 系统,就如我前面阐述的一样,一致性不应该是 NoSQL 出现的理由,去 SQL 和关系模型才是 NoSQL 出现的动力。但我并不认为 NoSQL 会代替 SQL。虽然 NoSQL 出现的时候,原本表达的意思是 “NO SQL(没有 SQL),但是我觉得另外一种对 NoSQL 的解释更合适,也就是“Not Only SQL不仅仅有 SQL)”。NoSQL 不是 SQL 的替代品,应该是 SQL 的有力补充。在 NoSQL 运动中,涌现出来的非常优秀的 NoSQL 系统大多都有自己的独有的接口协议,比如 Redis、MongoDB、Cassandra、图数据库等等。他们都有各自非常适用的使用场景,比如 MongoDB 贴近面向对象,图数据库适合节点的图关系运算。而 Redis 贴近开发者数据结构思维,相信每个开发者都是从数组、hash 表、队列这样的数据结构中成⻓起来的。

另外,Redis 本身是一个非常优秀的产品,它的普及程度非常高,特别是在互联网行业。在每个互联网公司,Redis 都已经成为工程师开发工具箱中,必备的工具之一。Redis 已经是开发者除 SQL 之外,第二熟悉的产品了。

但是,选择 Redis 协议,也给我带来一些实际的困扰,我们有些使用者最初接触 Tedis 时,总是拿我们和 Redis 相比。但是,虽然我们采用的是 Redis 接口,但是 Tedis 本身并不对标 Redis 这个产品。Redis 是非常优秀的缓存。虽然 Redis 也可以开启持久化功能,由于 Redis 本身架构设计,开启持久化的 Redis 仍然不能达到“实际上的 CA”(effectively CA),和 100% 的持久性(durability)。这是 Redis 和 Tedis 的一个很大的区别,Tedis 是一个数据库,不是一个缓存。

讨论完上面的 2 个架构思考,我们来看一下 Tedis 的架构设计。

image

在 Tedis 中,我们封装了一个 TiKV 的 SDK,对 Redis 的协议进行了解析,并且将 Redis 协议转成对 TiKV 的调用。

目前 Tedis 仍然有很多要完善的地方,但是我们会尽快完善如下的事项,在我们的开源日程表中:

1. Redis 命令的补全

2. 压缩和限流等一些扩展功能

3. Cassandra 协议的支持

写在最后

作为存储系统,不应该让使用者在一致性、可用性这些技术特性上做过多的选择,使用者应该更多的考虑哪种接口更适合自己的应用场景,自己更熟练使用哪种接口,能用哪种接口更快的进行功能开发。

由于篇幅所限,本文中关于强一致性、线性一致性、Redis、Raft、Spanner 的很多技术细节的阐述未能详尽,拟另行成文讨论。

参考资料:

  1. https://github.com/pingcap/tikv

  2. https://github.com/pingcap/TiDB

  3. Eventually Consistent - Revisited,Werner Vogels, 2008, http://www.allthingsdistributed.com/2008/12/event ually_consistent .html

  4. Linearizability: A Correctness Condition for Concurrent Objects,Maurice P. Herlihy and Jeannette M. Wing,1990

  5. In Search of an Understandable Consensus Algorithm, Diego Ongaro and John Ousterhout, 2014

  6. Spanner: Google’s Globally-Distributed Database, James C. Corbett, Jeffrey Dean et al., 2012

  7. F1: A Distributed SQL Database That Scales, Jeff Shute et al., 2013 8.Spanner: Becoming a SQL System, David F. Bacon et al., 2017

这篇关于Tedis:基于 TiKV 构建的 NoSQL 数据库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/382622

相关文章

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

嵌入式数据库SQLite 3配置使用讲解

《嵌入式数据库SQLite3配置使用讲解》本文强调嵌入式项目中SQLite3数据库的重要性,因其零配置、轻量级、跨平台及事务处理特性,可保障数据溯源与责任明确,详细讲解安装配置、基础语法及SQLit... 目录0、惨痛教训1、SQLite3环境配置(1)、下载安装SQLite库(2)、解压下载的文件(3)、

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

MySQL追踪数据库表更新操作来源的全面指南

《MySQL追踪数据库表更新操作来源的全面指南》本文将以一个具体问题为例,如何监测哪个IP来源对数据库表statistics_test进行了UPDATE操作,文内探讨了多种方法,并提供了详细的代码... 目录引言1. 为什么需要监控数据库更新操作2. 方法1:启用数据库审计日志(1)mysql/mariad

postgresql数据库基本操作及命令详解

《postgresql数据库基本操作及命令详解》本文介绍了PostgreSQL数据库的基础操作,包括连接、创建、查看数据库,表的增删改查、索引管理、备份恢复及退出命令,适用于数据库管理和开发实践,感兴... 目录1. 连接 PostgreSQL 数据库2. 创建数据库3. 查看当前数据库4. 查看所有数据库

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Oracle 数据库数据操作如何精通 INSERT, UPDATE, DELETE

《Oracle数据库数据操作如何精通INSERT,UPDATE,DELETE》在Oracle数据库中,对表内数据进行增加、修改和删除操作是通过数据操作语言来完成的,下面给大家介绍Oracle数... 目录思维导图一、插入数据 (INSERT)1.1 插入单行数据,指定所有列的值语法:1.2 插入单行数据,指

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手