微信自用高性能通用键值组件MMKV已开源!

时间:2020-10-20

企业内部通讯软件

腾讯微信团队在2018年9月底宣布了开源MMKV,这是一个基于mmap内存映射的关键价值组件。底层的序列化/反序列化由protobuf实现,注重高性能和稳定性。最近,它也被移植到了安卓平台上,并且对外界是开源的。

 简介

 MMKV是一个基于mmap内存映射的键值组件,底层的序列化/反序列化由protobuf实现,具有高性能和强稳定性。从2015年年中开始,它已经在iOS微信上使用了近3年,其性能和稳定性已经过时间验证。最近,它也被移植到了安卓平台,并且是开源的。

 最新源代码托管地址:https://github.com/Tencent/MMKV

 MMKV从源头开始

 在微信客户的日常操作中,特殊字符会不时出现(请参考文章《微信团队共享:微信iOS版如何防止特殊字符导致的群体爆炸和应用崩溃?》“微信团队共享:iOS版微信高性能通用键值组件的技术实践”,本文设计的技术方案是在键码前后加减计数器,通过检查计数器的异常来发现引起闪回的异常词。在小区数量较多的地方,如通话列表和通话界面,希望新增加的定时器不会影响滑动性能;此外,这些计数器应该永久存储,因为闪回可以随时发生。

 因此,需要高性能的通用键值存储组件。我们调查了常见的组件,如共享参考、NSUserDefaults和SQLite,发现它们都不能满足如此严格的性能要求。考虑到该防崩溃方案的主要需求是实时写入,而mmap内存映射文件正好满足这一需求,我们尝试通过它实现一组键值组件。

 MMKV原理

 记忆准备

 mmap内存映射文件提供了一个可以随时写入的内存块。应用程序只向其中写入数据,操作系统负责将内存写回文件,因此无需担心崩溃导致的数据丢失。

 数据结构

 在数据序列化方面,我们选择了protobuf协议,pb在性能和空间占用方面都有很好的表现。

 写优化

 考虑到主要的使用场景是频繁的写更新,我们需要增量更新的能力。我们考虑序列化增量kv对象,并将其附加到内存的末尾。

 空间增长

 使用追加实现增量更新带来了一个新问题,即如果您继续追加,文件大小将无法控制地增长。我们需要在性能和空间之间做出妥协。

 有关更详细的设计原则,请参考MMKV原则。

 监督办指南

 安装导入

 建议使用椰子肉:

 安装光盘;;

 打开命令行,cd到您的项目目录,并输入pod repo更新,使CocoaPods知道最新的MMKV版本;

 打开Podfile并将Pod“MMKV”添加到您的应用程序目标中;

 在命令行中输入podinstall

 打开;xcworkspace文件由带Xcode的CocoaPods自动生成;

 添加头文件#import,您可以愉快地开始您的MMKV之旅。

 有关更多安装说明,请参见iOS设置。

 快速开始

 MMKV的使用非常简单,无需任何配置,并且所有更改都会立即生效,无需调用同步:

 毫米千伏*毫米千伏=[毫米千伏默认值毫米千伏];

 [mmkv SetBool:YES ForKey:@ " bool "];

 BOOL Bvalue =[mmkv GetBOOLfWorkey:@ " BOOL "];

 [mmkv setint 32:-1024 ForKey:@ " int 32 "];

 int 32 _ t iValue =[mmkv getint 32 forkey:@ " int 32 "];

 [mmkv setObject:@"hello,mmkv " ForKey:@ " string "];

 nsString * str =[mmkv GetObjectOfClass:NSString . class分叉:@ " string "];

 有关更详细的教程,请参见iOS教程。

 性能比较

 随机写入int 1w次,我们有以下性能比较:

 有关更详细的性能比较,请参见iOS基准测试。

 安卓指南

 安装导入

 建议使用Maven:

 依赖关系{

 实现' com.tencent:mmkv:1.0.10 '

 //用任何可用版本替换“1.0.10”

 }

 更多安装说明,请参见安卓系统。

 快速开始

 MMKV的使用非常简单,所有的更改都会立即生效,无需调用同步或应用。应用程序启动时初始化MMKV,并设置MMKV的根目录(文件/mmkv/),例如,在维护活动中:

 受保护的无效创建(捆绑保存状态){

 super.onCreate(保存状态);

 字符串rootDir = MMKV.initialize(此);

 System.out.println("mmkv根:"+rootDir);

 //……

 }

 MMKV提供了一个可直接使用的全球示例:

 import com . Tencent . mmkv . MMKV;

 //……

 MMKV kv = MMKV . DefaultMMKV();

 kv . encode(“bool”,真);

 布尔Bvalue = kv . DeCodebool(" bool ");

 千伏编码(“整数”。最小值);

 int iValue = kv . DeCodeInt(“int”);

 编码(“字符串”、“你好,来自mmkv”);

 字符串字符串= kv.decodeString(“字符串”);

 MMKV支持多进程访问。请参考安卓教程了解更多详细用法。

 性能比较

 写随机整数1千次,我们有以下性能比较: