我们最近推出了 EloqKV,这是一个基于创新性 数据基底 架构构建的分布式数据库产品。在过去几年中,EloqData 团队一直在不懈努力开发这款软件,确保它能够满足最高的性能和可扩展性标准。这里我们想分享一个关键细节:EloqKV 的大部分代码是用 C++ 编写的。

如果我们在十年前推出这个产品,使用 C++ 会是一个显而易见且不值得一提的选择。然而,现在是 2024 年,形势已经发生了变化。如今,像 Rust、Zig 这样的语言,以及其他类型安全的选项如 Golang 被认为是现代和流行的系统编程语言。因此,当我们选择 C++,一个可能被一些人视为过时或不够"酷",甚至容易出错和"不安全"的语言时,人们自然会好奇为什么。
在这篇文章中,我们想分 享我们选择 C++ 而不是一些更新、更时髦的语言背后的思考过程,我们从历史中汲取的经验教训,以及我们对未来发展的期望。
选择编程语言很重要
对于任何软件项目来说,选择正确的编程语言都至关重要,但对于像数据库这样的复杂系统软件来说,这一选择变得更加重要。语言的选择会影响各个方面,包括性能、开发便利性和可维护性。在效率和可靠性至关重要的领域,编程语言是整个系统构建的基础。
对于数据库而言,这个选择的影响更为深远。数据库必须能够处理海量数据,同时提供快速的查询响应并确保数据完整性。这些要求需要一种不仅在性能上出色,而且能够支持可扩展和高效开发实践的语言。此外,数据库通常需要经过数十年的持续开发和增强,这使得可维护性成为一个关键因素。一个选择得当的语言可以简化软件功能的更新和扩展过程,确保它在不断发展的技术环境中保持相关性和有效性。
以 Hadoop 大数据技术栈为例,它主要建立在 Java 虚拟机 (JVM) 之上。虽然 Java 和 JVM 生态系统一直是最受欢迎的编程语言家族之一,并因其可移植性和丰富的功能而备受赞誉,但回顾过去,这个选择可能并非没有争议。JVM 的性能和内存开销,特别是与垃圾收集相关的问题,给开发者带来了诸多挑战。事实上,RedPanda 和 ScyllaDB 就是从头开始用 C++ 重写成熟、广泛使用的基于 Java 的框架 —— Kafka 和 Cassandra 的典型例子,目的就是为了避免 JVM 的性能损失。
另一个重要的考虑因素是编程语言的普及程度和熟悉该语言的开发者的可用性。例如,Spark 和 Kafka 是用 Scala 开发的,而 Couchbase 和 Rabbitmq 则使用 Erlang。尽管这些语言提供了强大的功能和能力,但它们并没有像其他编程语言那样被广泛采用。这种相对较低的普及度可能会在大规模开发者参与和寻找有经验的程序员方面带来挑战。工具链支持通常也不如更流行的编程语言。使用较少见的语言可能会增加招聘人才的难度,减缓开发进程,并限制社区对故障排除和创新的支持。
到 2010 年代后期,Rust 已成为开发数据库软件的主要编程语言之一。像 TiDB、RisingWave、DataFusion 和 NeonDB 这样的新项目都是利用 Rust 的能力来构建高效和高质量数据库的突出例子。值得注意的是,RisingWave 甚至发表了一篇博客文章,详细说明了他们放弃十个月的 C++ 工作,重写整个代码库到 Rust 的决定。考虑到 EloqData 是在 2021 年左右开始其旅程的,当时 Rust 已经确立为一个用于构建安全和高性能数据库的强大编程语言,人们可能会好奇为什么我们选择了 C++。
在 2024 年用 C++ 从头构建数据库
当我们开始这个项目时,我们清楚地意识到 Rust 是构建数据库基础的一个极具竞争力的语言。我们最终选择 C++ 是基于三个主要因素。
C/C++ 的第一个优势在于其数据库生态系统支持。大多数现有和流行的数据库都是用 C/C++ 开发的,这提供了大量我们可以利用的资源和创新。我们的数据基底技术旨在创建一个统一的、模块化的架构,可以利用这些现有资源,同时避免重新发明轮子。虽然 Rust 提供了良好的 C/C++ 互操作性,但其内存管理模型和某些安全限制可能会使与许多既有项目的集成变得复杂。
C++ 的另一个优势是其对基础库的广泛支持。由于大多数操作系统和底层驱动程序都是用 C 或 C++ 编写的,这些语言的绑定通常是原生的且最受支持的 API。面向性能的 IO 和网络库,如 DPDK、RDMA 和 liburing