1.前言
本文将分享一个高性能通用键值组件在iOS版微信中推广使用的技术实践过程。该组件在微信中被命名为MMKV(以下简称MMKV)。
MMKV是一个基于mmap内存映射的键值组件,底层的序列化/反序列化由protobuf实现,具有高性能和强稳定性。我希望拥有高性能关键价值组件或类似技术要求的即时消息同行能够通过本文得到一些启发。
最新消息:微信团队于2018年9月底正式开通了该MMKV组件。源代码地址:https://github.com/Tencent/MMKV,中文描述:https://github.com/Tencent/MMKV/blob/master/readme_cn.md
2.从MMKV源开始
在iOS微信的日常运行中,会不时出现特殊字符,这将导致iOS系统崩溃。“微信团队共享:iOS版本的微信如何防止由特殊人物引起的群体爆炸和应用崩溃?本文设计的技术方案是在关键码前后加、减计数器,通过检查计数器的异常来发现引起闪回的异常词。
“微信团队共享:iOS版本的微信如何防止由特殊人物引起的群体爆炸和应用崩溃?“”中设计的技术方案的一般原则是:
1)在有大量小区的地方,如通话列表和通话界面,希望新增加的定时器不会影响滑动性能;
2)这些计数器应该永久保存——因为闪回可以随时发生。
这需要一个具有非常高性能的通用键值存储组件。我们调查了一些常见的组件,如NSUserDefaults和SQLite,发现它们都不能满足如此严格的性能要求。考虑到该防崩溃方案的主要需求是实时写入,而mmap内存映射文件正好满足这一需求,我们尝试通过它实现一组键值组件。
3.MMKV原理
3.1记忆准备
mmap内存映射文件提供了一个可以随时写入的内存块。应用程序只向其中写入数据,iOS负责将内存写回文件,因此无需担心崩溃导致的数据丢失。
3.2数据组织
在数据序列化方面,我们选择了protobuf协议,pb在性能和空间占用方面都有很好的表现。考虑到我们想要提供的是一个通用kv组件,密钥可以被限制为字符串类型,并且值是多种多样的(int/bool/double等)。)。为了通用,考虑通过protobuf协议将值序列化到统一的缓冲区中,然后将这些KV对象序列化到内存中。
微信团队共享:微信高性能通用关键价值组件技术实践iOS版_1.jpeg
有关Protobuf的更多文章,请参见:
Protobuf通信协议详细说明:代码演示、详细原理介绍等。
强烈建议使用Protobuf作为您的即时通讯应用程序数据传输格式
综合评估:Protobuf的性能比JSON快五倍吗?》
基于协议缓冲区的Java代码演示
详细解释如何在节点中使用谷歌的原型
3.3写优化
标准protobuf不提供增量更新功能,每次写入都必须完整写入。
考虑到主要的使用场景是频繁的写更新,我们需要增量更新的能力:
序列化增量kv对象,并将其直接追加到内存末尾;
这样,相同的键将有新的和旧的数据,而最新的数据将在最后;
然后,当程序第一次开始打开mmkv时,只需要不断地用以后读入的值替换以前的值,这样就可以保证数据是最新的和有效的。
3.4空间增长
使用追加实现增量更新带来了一个新问题,即如果您继续追加,文件大小将无法控制地增长。例如,如果同一密钥不断更新,可能会消耗数百m甚至g的空间,但实际上,整个kv文件只有一个密钥,可以保存在不到1k的空间中。这显然是不可取的。
我们需要在性能和空间之间做出妥协:
在内存页面大小中申请空间,在空间耗尽之前处于追加模式;
当追加到达文件末尾时,重新组织文件并键入副本,并尝试序列化和保存副本结果;
如果在移除重载后没有足够的空间,请将文件加倍,直到有足够的空间。
微信团队共享:微信高性能通用关键价值组件技术实践2.jpeg的iOS版本
3.5数据有效性
考虑到文件系统和操作系统的不稳定性,我们增加了crc校验来区分无效数据。在iOS微信实时网络环境中,我们观察到平均约有70w的数据验证失败。
4.MMKV的使用
4.1快速开始
MMKV提供了一个可直接使用的全球示例:
微信团队共享:微信高性能通用关键价值组件技术实践iOS版_3.jpeg
可以看出,MMKV的使用相对简单。如果不同的企业需要不同的存储,您也可以单独创建自己的实例:
微信团队共享:微信高性能通用关键价值组件技术实践iOS版_4.jpeg
4.2支持的数据类型
支持以下基本类型的c语言:
bool、int32、int64、uint32、uint64、float、double
支持以下对象类型:
NSString、NSData、NSDate
5.MMKV性能
编写一个简单的测试来比较MMKV和NSUserDefaults的性能(循环编写1w倍的数据,测试环境:iPhone X 256G,iOS 11.2.6,单位:毫秒)。
微信团队共享:微信高性能通用关键价值组件技术实践iOS版_5.jpeg
可以看出,MMKV的性能远远优于iOS的用户默认值。此外,在测试中,发现NSUserDefaults每隔2-3次测试就会有一次耗时的操作,这被怀疑会触发数据同步和重组写入。相比之下,即使MMKV触发了数据重组,它也能保持稳定高效的性能。
----------------------------------------------------------------------------------
哇谷im_im即时通讯_私有云_公有云-哇谷云科技官网-JM沟通
IM下载体验 - 哇谷IM-企业云办公IM即时聊天社交系统-JM 沟通下载
IM功能与价格 - 哇谷IM-提供即时通讯IM开发-APP搭建私有化-公有云-私有化云-海外云搭建
新闻动态 - 哇谷IM-即时通讯热门动态博客聊天JM沟通APP
关于哇谷-哇谷IM-提供企业即时通讯IM开发-语音通话-APP搭建私有化-公有云-私有化云-海外云搭建
联系我们 - 哇谷IM-即时通讯IM私有化搭建提供接口与SDK及哇谷云服务
公有云和私有云之间有什么区别?类似融云、环信云、网易云、哇谷云?