Java与数据库:从质疑到实践的十年探索

从16年开始参与时序数据库 IoTDB的研发,时不时的会被问到,你们为什么用Java写数据库?Java 能用来写数据库吗?

最开始我会讲,"在 IoTDB 起步的2011年,几乎所有知名系统、数据库,都采用 Java 进行开发,像 Hadoop、Hbase、Spark(基于JVM的scala)、Cassandra、Kafka、Flink,为了和大数据生态的紧密结合,IoTDB 自然选择了 Java 进行开发。"

这是一个原因,但我相信大家想了解的绝对不仅仅是这些。那么,学了Java,有没有机会做数据库?Java 能不能做出好的数据库?选择 Java 开发,对于 IoTDB 意味着什么?

这些问题无法通过理论推导,Java与数据库,是语言、系统、投入、回报的辩证组合,只能实践出真知。而我们经过了近 10 年的探索,今天来重新回答这个问题,主要有以下 8 个方面的考虑。

  1. Java 生态丰富

队列、Map、堆、锁、线程控制等,凡是通用的数据结构和算法,几乎都有成熟的实现,这让我们可以把精力投入到数据库逻辑优化中,而不是重复造轮子。

此外,大量的平台和应用在使用 Java 开发,Java 生态的中间件和软件互相集成的便捷度很高,也促使了 Java 应用开发者对 Java 语言的数据库的可掌握程度就更高。

  1. 可读性

这个点没有放在第一位,是因为大家一般不太会关注,但是作为一个长年摸爬滚打的数据库研发者,这个因素也非常重要。

数据库的高复杂度,不仅仅带来巨大的优化空间,也同时带来了极度危险,稍不注意就会写入 bug,这也是为什么有的数据库新版本会比老版本的性能和稳定性差很多。

而面向对象的 Java,在代码可读性和易理解层面,具备天然优势。在和社区贡献者的交流过程中,发现大家对 IoTDB 的设计原理基本能够很快上手。

代码可读性是一个系统的生命力,可读的代码才能让一个系统在演进过程中保持长期的活力。

  1. 运维难度

相信 Java 开发者都会对其异常捕获机制和在日志中打印的堆栈印象深刻。这些堆栈信息能够帮我们快速定位问题并进行修复。印象中,如果用户反馈 IoTDB 的 bug,通常能根据堆栈信息,在当天定位问题原因并进行修复,很少超过 1 天的。

之前和一些 C 语言数据库的开发者交流,遇到内存泄露等线上问题时,排查时间在一个月以上都是可能的。

和数据库整体稳定性相比,任何语言特征优势都要靠后,没有什么比线上数据库出问题不能快速修复更让人崩溃了。JProfiler、Arthas等JVM运维神器能够帮助 Java 开发者快速定位到问题原因,及时修复。

  1. 跨平台

最近这个词有另一个叫法:国产化适配。Java的目标就是"一次编译,到处运行",随着这几年国产硬件的大范围普及,我们几乎没有做过任何特殊的适配工作,只要能装上Java就能使用IoTDB。让我们能够把精力放在数据库内在逻辑的优化和打磨。

  1. 便捷的项目管理

参与 IoTDB 项目学习的第一个技能就是 Java 项目管理工具 Maven。不论大小,Java 项目几乎都在使用 Maven 进行管理。包括代码结构组织、依赖管理、编译、打包、版本发布等,一些代码格式化、静态检查等高级操作也能通过自定义的 profile 一气呵成,上手非常快,我写博客的起点就是介绍 maven 项目的发版流程。

  1. 性能

相信这是大多数人会关注的,Java开发的数据库性能会高吗?

先放个事实,在目前主流的公开时序数据库榜单上,比如 TPCx-IoT、BenchAnt,IoTDB 在读写性能、成本维度都是第一。这些榜单中包括了Go语言的 Influxdb和VictoriaMetrics、C 语言的 TimescaleDB、C++语言的Clickhouse等。

Java 开发的 IoTDB,性能不仅不差,反而是最好的,这是什么原因?

数据库被誉为基础软件皇冠上的明珠,其研发难度之大超乎想象,这里的研发难度来自哪里?不是语言的复杂度,而是数据库内的逻辑复杂度。

随着数据库功能的丰富,数据库迭代演进的困难会随指数级增长,就像一个大型城市治理,有各种部门、流程、人员、资源要协调,也会越来越笨重冗余。这里面可以优化的点就非常多,列式存储、批量化、流水线、索引,很有可能一个细节流程的优化,就带来10倍的性能提升。

大家经常提到的Java垃圾回收,本身是一个正面特性,就像操作系统的内存碎片整理,全世界的优秀Java开发者实现的垃圾回收,整体表现还是不错的。特殊场景中如果需要专门优化,通过在数据库层面设计缓存、甚至使用堆外内存,也能够做到应用层无感。

数据库是个综合的系统,单一的技术优势和技术劣势都不足以定义一个数据库,在我们维护的线上环境从来没有碰到过 Java GC 算法表现不够的场景,如果碰到了严重 GC 停顿,要么是使用问题,要么是遇到了内存泄漏,但是这些问题在测试阶段通常当天就能掉解决了。

  1. 轻量化

也遇到有人关心,我们是端侧场景,Java 能做到轻量部署吗?这里分两个场景讨论。

第一种是智能终端,可能只是资源没那么多,单核 CPU、1-2G内存、几十G磁盘空间,但是也是有完整的软件开发环境的。这种都没啥问题,IoTDB 内存可以调节到百兆左右,性能完全能够满足边缘读写负载,目前 IoTDB 在卫星、机载、电力采集终端等的应用都是这种场景。

第二种是嵌入式场景,只支持 C/C++ 环境,内存几十兆,需要实时采集数据,存储上传。这种场景真的需要数据库吗?其实大多情况文件就够用,我们一般使用时序数据文件格式TsFile 的 C++ 版进行端侧存储,然后再将文件上传。(C++ TsFile 会于近期开源发布)

可能大家会想,端侧部署数据库能不能用来进行工业控制优化,或者控制算法需不需要长期历史数据进行计算?一般不会,控制算法的时间复杂度通常会控制在非常低的程度,保证控制实时性,即使需要一段时间的历史数据,也会采集后就全量缓存在内存里直接用,不会写数据库再读出来进行计算。

当终端向着智能化发展,硬件资源会越来越充足,我们需要更聚焦数据处理机制。

  1. Java人才济济

数据库公司和核心不仅仅是代码,还有一个靠谱的开发和运维团队。

数据库领域在前几年爆火的一段时间吸引了不少人参与,但是总体占比还是太少了。而优秀的 Java 开发者来参与数据库内核开发,这条路已经被我们反复验证是可行的,而且大家转型的效果往往很好,都能够快速维护起一个模块,开始投入代码贡献。


既然如此,大家为什么依然觉得 Java 不能写数据库呢?很大一部分原因在于,老牌关系数据库 Oracle、MySQL、PostgreSQL都不是 Java。

这其实是一个历史原因。传统关系数据库诞生于 1970 年,而 Java 是 1995 年才诞生的,在 Java 诞生时,这些数据库已经用 C 语言写了几十年了:Oracle(1977)、PostgreSQL(1986)、MySQL(1995)。

在 Oracle 成立之初,也有人对数据库能否成功商业化抱有疑问。而 Oracle 的成功用实践证明了数据库是可以商业化的。

Java 也是一样,很多高性能中间件和数据库都在用 Java 开发,包括 IoTDB、Cassandra、H2 等大量实践证明Java的性能是足够开发数据库的。

回顾 IoTDB 发展的十年时间,我们之所以能在近几年用户需求爆发时快速迭代出用户需要的核心功能,并且保持了高稳定性和性能,这里一定有 Java 的一份功劳。

Java 不仅能做数据库,而且很合适。这不是一个理论推导,而是实践结论。

如果你也是一位 Java 开发者,是完全有机会做出一款优秀数据库的,如果对 IoTDB 感兴趣,欢迎点击原文来 github 逛逛。

相关推荐
麦聪聊数据1 分钟前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务2 分钟前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
Ro Jace26 分钟前
计算机专业基础教材
java·开发语言
代码游侠42 分钟前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
mango_mangojuice44 分钟前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
程序员侠客行1 小时前
Mybatis连接池实现及池化模式
java·后端·架构·mybatis
devmoon1 小时前
运行时(Runtime)是什么?为什么 Polkadot 的 Runtime 可以被“像搭积木一样”定制
开发语言·区块链·智能合约·polkadot·runtmie
时艰.1 小时前
Java 并发编程 — 并发容器 + CPU 缓存 + Disruptor
java·开发语言·缓存
丶小鱼丶1 小时前
并发编程之【优雅地结束线程的执行】
java
市场部需要一个软件开发岗位1 小时前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全