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

相关文章

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

Python利用PySpark和Kafka实现流处理引擎构建指南

《Python利用PySpark和Kafka实现流处理引擎构建指南》本文将深入解剖基于Python的实时处理黄金组合:Kafka(分布式消息队列)与PySpark(分布式计算引擎)的化学反应,并构建一... 目录引言:数据洪流时代的生存法则第一章 Kafka:数据世界的中央神经系统消息引擎核心设计哲学高吞吐

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

MybatisPlus中removeById删除数据库未变解决方案

《MybatisPlus中removeById删除数据库未变解决方案》MyBatisPlus中,removeById需实体类标注@TableId注解以识别数据库主键,若字段名不一致,应通过value属... 目录MyBATisPlus中removeBypythonId删除数据库未变removeById(Se