sharedata 的替代品:datasheet

栏目: Lua · 发布时间: 7年前

内容简介:sharedata 的替代品:datasheet

skynet 中有一个用来在多个服务间共享数据表的模块,叫做 sharedata

它的设计动机是:当我们有很多服务时,如果需要共享一份只读的数据表,把数据表分别在每个服务类加载会很浪费内存。而且,一旦数据表有热更新的需求,分散在多个服务中的数据更新起来会比较麻烦。

我试过很多方案来达成这个需求,一直都不是特别满意。目前的 sharedata 模块是用的最久、使用项目最多的一个。虽然它基本可用,但使用它的同学也提出了一些问题,我对这些问题做了一些思考。

首先、它其实并不能完全共享一块内存。我们很难做到像 C 数据结构一样,一份只读的数据结构让多个读取者持有指针,完全共享同一块内存。因为对于树结构的数据,如果期望让 lua 用原生的语法来访问,就需要把子结构的指针用 lua userdata 封装起来,这个结构本身是属于 lua vm 的,每个 vm 必须独立,不能共享。它是需要额外占用内存的。

如果把这个结构用 lightuserdata 封装,一是元表的问题很难解决的很好(不同的 lightuserdata 必须共享元表),二是 lightuserdata 无法做热更新:你很难(并非完全不行)通过遍历 lua vm 更新它。

而从节约内存的角度看这个模块的用途,它更多的是做到部分加载:策划会把很多数据打包到一个数据表里,但是一个服务在一段时间只会用到很少的一部分。把整个数据表加载到服务的 lua vm 内是很浪费内存的。

访问速度也是可能成为问题:lua 访问纯 table 的内容还是很快的,如果是 userdata 或带 metatable 的 table 的话,由于要至少多出一次函数调用,性能就大打折扣。sharedata 做了一定的 cache ,我们有一个项目在使用的时候更是自己额外多做了一层 cache ,为了配合 cache 工作,我还特定添加了 deepcopy 方法,把 sharedata 的子树复制成普通的 lua 表。这也可以看出,完全共享内存而减少内存消耗的需求并不那么强烈。

sharedata 在实现的时候,把数据热更新、副本引用管理的部分写在 C 层次,给实现也带来了不必要的复杂度。理论上热更新时,时间效率是很次要的,我们只需要保证正确即可,多长时间可以更新好并不太重要。

我在综合以上重新考虑后,最近重新实现了一个替代模块,暂命名为 datasheet 。它能做的是:把一个复杂的有一定限制的 lua 表,转换为一块 C 内存,由多个 lua 服务共享读取。

这里的一定限制指:表项的 key 只能是字符串,或是正的连续整数(数组)。加上这个限制可以简化实现。

它和 sharedata 的实现有所不同:它仅在第一次访问一个子表时,利用元方法触发,将子表的第一层完全复制到当前的 lua vm 中;如果这一层下还有子表,则只创建一个空表,附上元方法,惰性展开。展开后,它就变成了 lua 中一个普通 table ,原表也已去掉,访问操作完全没有效率损失。

从 lua 表转换为 C 内存块的过程交给独立的子模块 datasheet.builder 来完成,并由调用这个模块的服务来保持 C 内存块的生命期。这个 C 内存块将以 lua string 的形式存在于调用 datasheet.builder 的 lua 服务的 vm 中,只是把字符串指针共享给其它服务。

而任何服务一旦引用一张表,都可以把生命期保持到该服务退出。这些数据表采用引用数据管理,管理部分全部由 lua 实现。

数据热更新是这样实现的:

任何转换为 C 内存的数据表,每个子表都有一个唯一数字 id 。对应在 lua vm 中是一个包含有这个数字 id 的 userdata 。而在需要热更新数据表的时候,需要把老版本的数据表和新版本的数据表做一次差异比较,根据表项的 key 找到新老对应项,尽量保持相同的 id 生成新版本的数据块。

这样,在做热更新的时候,只要通知持有旧表的服务,更新 C 数据块指针,并把 vm 中的 cache 清空,下次访问任何一个子表时,重新从 C 数据块展开数据即可。

目前 datasheet 已经提交到 skynet 的 master 主干,以一个独立模块存在,接口方面和 sharedata 大致相同。有兴趣尝试的同学可以帮忙测试一下。它以后很有可能作为 skynet 1.1 的默认模块提供。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

MySQL入门很简单

MySQL入门很简单

黄缙华 / 清华大学出版社 / 2011-1 / 59.50元

《MySQL入门很简单》从初学者的角度出发,由浅入深,循序渐进地介绍了mysql数据库应用与开发的相关知识。书中提供了大量操作mysql数据库的示例,还提供了大量实例和上机实践内容,供读者演练。《MySQL入门很简单》附带1张dvd光盘,内容为与《MySQL入门很简单》内容完全配套的多媒体教学视频和《MySQL入门很简单》涉及的源代码。 《MySQL入门很简单》共分5篇。第1篇介绍数据库的基......一起来看看 《MySQL入门很简单》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换