最近花了些时间,将引擎的存储换成了 mongodb。

私下,我觉得现有的存储机制极为落后。现在写数据的操作交由单独的进程完成,该进程兼当数据缓冲与持续化数据的责任。此次引擎的更换,只是简单的利用 mongo 的官方 c 驱动,将数据打到 mongo 里面,代替写文件的做法而已。该进程的数据缓冲角色,还是没有变化。mongodb 的优势在于对内存的高效利用,增加一层作为中转,就会失去这个速度上的优势。

往引擎里添加 mongo,比较头大的是跟引擎脚本的类型系统打交道。比较了一下 BSON 支持的数据格式,能够比较好的容纳引擎的数据。但是引擎的关联数组(类似 python 的 dict)和异构数组,在 C 层用起来不太方便。引擎这边的类型,都是用一个 svalue 进行封装,里面用 union 包装 int、float 等基础类型,以及字符串指针和数组等引用类型。但是,svalue 的打包却需要手工做,没有封装方便的打包函数。关联数组的使用还算方便,只要构造好 key 和 value 的 svalue 值,调用 find_for_insert,然后 assign_svalue 就可以了。

剩下的主要是对象的生命周期管理。连接对象由数据库连接池进行管理,如果多线程读写时有线程 hang 住,该连接就不会被释放了。用于传送数据到数据库的 bson 对象,会在每次传送完成后被释放,这里应该没有问题。从数据库序列化为引擎的数据对象时,产生的关联数组等数据交由 vm 进行管理,这块是通过引用计数做的,要分析泄漏的问题,可能要结合具体的脚本进行分析了。

性能方面,还没有进行测量,打算通过 Dtrace 或者 SystemTap 进行,顺便用 valgrind 做做内存泄漏检测。瞎猜测一下,socket 进行数据中转和序列化对象可能会是瓶颈。