热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

『每周译Go』YYDS!Go如何编写简单的内存键值数据库

从Postgres到Redis,再到Prometheus,我们都使用并从事过各种数据库的开发。我花了很多时间来阅读其中一些数据库的源代码,

4a835635d35f934aba3e565b577e5196.png

从 Postgres 到 Redis,再到 Prometheus,我们都使用并从事过各种数据库的开发。我花了很多时间来阅读其中一些数据库的源代码,对于那些像我一样好奇的少数人来说,他们有兴趣学习如何编写一个数据库。本书旨在记录这一过程。

GitHub-arriqaaq/flashdb:

FlashDB is an embeddable, in-memory key/value database in Go (with Redis like commands)

01

内存数据库 

传统数据库的数据主要保存在机械硬盘或者固态硬盘, 内存数据库则主要将数据保存在内存中,并通过消除对磁盘的访问来实现最小的响应时间。两者的不同主要体现在内存数据库是将数据保存在主存或者 RAM 中,而传统的数据库则是通过驱动磁盘来获取数据。

内存数据库相比传统数据库更不稳定,由于所有的数据都存储与管理在主存中,当计算机断电或 RAM 崩溃时,数据将会丢失。

内存数据库可以通过将每个操作存储在日志中或采取快照的方式在磁盘上持久化数据

02

目标 

我们的目标是用 Go 编写一个简单、快速、嵌入式和可持久化的键/值数据库,并且实现以下功能:

  • 支持类似 Redis 的数据结构string, hash, set, zset

  • 具有低延时和高吞吐量

  • 支持事务,ACID 语义

  • 仅可写入的持久化文件格式

  • 可以通过使用 TTL 来处理数据过期

03

开始

我们要建立的是一个非常简单的 KV(键/值)存储,以便让每个人都能轻松理解和实现。在 Go 中,有相当多的嵌入式键/值存储可用,以下是一些例子:

  • BadgerDB - BadgerDB 是一个完全用 Go 编写的嵌入式、可持久化、简单而快速的键值(KV)数据库。它旨在成为 RocksDB 等非基于 Go 实现的键值存储的高性能替代品

  • BoltDB - BoltDB 是一个基于 B+ 树的嵌入式 Go 键/值数据库

  • BuntDB - BuntDB 是一个应用于 Go 的嵌入式内存键/值数据库,具有自定义索引和地理空间支持

  • go-memdb - 基于不可变基数树的 Golang 内存数据库

  • nutsdb - 一个基于磁盘的键值存储

读起来容易做起来难。虽然我们可以通过阅读庞大的代码库来了解其内部结构,但这对很多人来说依旧是一个障碍。我们的初衷是为任何想学习关于如何编写一个简单的 ACID 数据库的新手提供桥梁。

NutsDB 是我在 2-3 年前读到的第一批简单易懂的代码之一。因此,我们选择由易于理解的组合库组成的FlashDB。

04

架构 

FlashDB 的架构很简单并且支持各种 Redis 命令。Redis 本质上不是一个普通的键值存储,而是一个数据结构服务器,支持不同种类的值。事实上,Redis 使用以下数据结构实现了各种类型。

27266d5c4869de8a0d97b51f492ee694.png

05

字符串

Redis 字符串类型是能与 Redis 键关联的最简单的值类型。由于 Redis 键是字符串,当我们把字符串类型也作为一个值时,实际上是把一个字符串映射到另一个字符串。这是用可变基数树(ART)实现的,这样可以很容易进行扫描。

  • String

 (https://github.com/arriqaaq/skiplist)

06

哈希

用哈希表示对象很方便,而实际上哈希中可放入的字段数量并没有实际限制(除了可用的内存),所以你可以在应用程序中以许多不同的方式使用哈希。这是用一个非常简单的 HashMap 数据结构实现的。

  • Hash

    (https://github.com/arriqaaq/hash)

07

集合 

Redis 集合是无序的字符串集合。我们可以对集合进行一些操作,比如检测某个元素是否已经存在,查找多个集合之间的交集、并集或差集等。这也是用一个简单的 HashMap 数据结构实现的。

  • Set

(https://github.com/arriqaaq/set)

08

有序集合 

有序集合是一种数据类型,类似于集合与哈希的混合体。和集合一样,有序集合也是由唯一的、不重复的字符串元素组成的。所以从某种意义上说,有序集合也是一个集合。

虽然集合内的元素并不是有序的,但有序集合中的每个元素都与一个浮点值相关,称为分数(该类型类似于哈希,因为每个元素都被映射到一个值)。

这是对用于字符串的跳表结构稍加修改实现的。

  • ZSet 

    (https://github.com/arriqaaq/zset)

09

持久化

虽然已经有了很多持久化机制,但我选择了一个简单的 append-only 日志设计方式,因为它比较容易实现和理解。

AOF(仅可写入的文件)记录了服务器收到的每一个写操作,这些操作将在服务器启动时再重放,重建原始数据集。命令的记录格式与 API 协议本身相同,以只写入的方式进行。当日志过大时,FlashDB 能够在后台分片处理日志。这是基于 wal 实现的。

  • Append Only Log

    (https://github.com/arriqaaq/aol)

总结

综上,FlashDB 仅依靠上述五个简单的库就完成了,具有事务与 ACID 支持,易于理解。但我希望这对任何有兴趣学习如何编写数据库的人来说都是一个有用的教程。

GitHub - arriqaaq/flashdb: 

FlashDB is an embeddable, in-memory key/value database in Go (with Redis like commands)

讲座

最近在 Golang meetup 上分享了这个项目,这是幻灯片的内容:

https://www.canva.com/design/DAE8sGRyC2o/ZCuCaezQ6dYA0Oq24QxjUQ/view?utm_content=DAE8sGRyC2o&utm_campaign=designshare&utm_medium=link&utm_source=publishsharelink

原文地址:

https://aly.arriqaaq.com/building-a-database-in-go

原文作者:Farhan Aly

本文永久链接:https://github.com/gocn/translator/blob/master/2022/w17_Writing_a_simple_in-memory_key-value_Database_in_Go.md

译者:张宇

校对:小超人

想要了解更多相关的内容,欢迎扫描下方👇 关注 公众号,回复关键词 [实战群]  ,就有机会进群和我们进行交流~

184dffc9c2e346e5bd0e4a7fc810ae6a.png

分享、在看与点赞,至少我要拥有一个叭~

add4ffbc9630b8ea10a4f443676fb76f.gif

511df96253cf3169783803c372e91595.gif


推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
author-avatar
手机用户2602919091
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有