LevelDB 源码阅读:MemTable 内存表的实现细节

0 Comment

在 LevelDB 中,所有的写操作首先都会被记录到一个 Write-Ahead Log(WAL,预写日志)中,以确保持久性。接着数据会被存储在 MemTable 中,MemTable 的主要作用是在内存中有序存储最近写入的数据,到达一定条件后批量落磁盘。

LevelDB 在内存中维护两种 MemTable,一个是可写的,接受新的写入请求。当达到一定的大小阈值后,会被转换为一个不可变的 Immutable MemTable,接着会触发一个后台过程将其写入磁盘形成 SSTable。这个过程中,会创建一个新的 MemTable 来接受新的写入操作。这样可以保证写入操作的连续性,不受到影响。

在读取数据时,LevelDB 首先查询 MemTable。如果在 MemTable 中找不到,然后会依次查询不可变的 Immutable MemTable,最后是磁盘上的 SSTable 文件。在 LevelDB 的实现中,不管是 MemTable 还是 Immutable MemTable,内部其实都是用 class MemTable 来实现的。这篇文章我们来看看 memtable 的实现细节。

阅读全文

LevelDB 源码阅读:结合代码理解多版本并发控制(MVCC)

0 Comment

在数据库系统中,并发访问是一个常见的场景。多个用户同时读写数据库,如何保证每个人的读写结果都是正确的,这就是并发控制要解决的问题。

考虑一个简单的转账场景,开始的时候 A 账户有 1000 元,要转 800 元给 B 账户。转账过程包括两步:从 A 扣钱,给 B 加钱。恰好在这两步中间,有人查询了 A 和 B 的余额。

如果没有任何并发控制,查询者会看到一个异常现象:A 账户已经被扣除了 800 元,只剩 200 元,B 账户还没收到转账,还是原来的金额!这就是典型的数据不一致问题。为了解决这个问题,数据库系统需要某种并发控制机制

最直观的解决方案是加锁,当有人在进行写操作(如转账)时,其他人的读操作必须等待。回到前面的问题,只有在转账的两步都完成之后,才能查到正确的账户余额。但是锁机制存在明显的问题,每次只要写相关 key,所有读该 key 的操作都要排队等待,导致并发上不去,性能会比较差。

现代数据库系统普遍采用 MVCC 来控制并发,LevelDB 也不例外,接下来我们结合源码来理解 LevelDB 的 MVCC 实现。

阅读全文

使用 Cursor 深度体验 3 个 MCP Server,惊艳但并不实用?

3 Comments

大语言模型刚出来的时候,只是通过预训练的模型来生成回答内容。这个时候的模型有两个主要的缺点:

  1. 有些数据它不知道,比如 2024 年 3 月训练的模型,就不知道 2024 年 5 月的事情;
  2. 没法使用外部工具。这里的工具我们可以等效理解为函数调用,比如我有个发表文章的工具函数,我没法用自然语言让大模型来帮我调用这个函数。

为了解决这两个问题,OpenAI 最先在模型中支持了 function calling 功能,他们在这篇博客: Function calling and other API updates 有介绍。

背景:理解 Function Calling

这时候,我们就可以告诉模型,我有这么几个工具,每个工具需要什么参数,然后能做什么事情,输出什么内容。当模型收到具体任务的时候,会帮我们选择合适的工具,并解析出参数。之后我们可以执行相应的工具,拿到结果。并可以接着循环这个过程,让 AI 根据工具结果继续决定往下做什么事情。

我在网上找了个动图,可以来理解下有了 function calling 后,做事情的流程:

理解 function calling过程理解 function calling过程

阅读全文