微信自用高性能通用key-value组件MMKV已开源!
1、MMKV简介
腾讯微信团队于2018年9月底宣布开源 MMKV ,这是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,主打高性能和稳定性。近期也已移植到 Android 平台,一并对外开源。
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今,在 iOS 微信上使用已有近 3 年,其性能和稳定性经过了时间的验证。近期也已移植到 Android 平台,一并开源。
MMKV最新源码托管地址:https://github.com/Tencent/MMKV
2、MMKV 源起
在微信客户端的日常运营中,时不时就会爆发特殊文字引起系统的 crash(请参见文章:《微信团队分享:iOS版微信是如何防止特殊字符导致的炸群、APP崩溃的?》、《微信团队分享:iOS版微信的高性能通用key-value组件技术实践》),文章里面设计的技术方案是在关键代码前后进行计数器的加减,通过检查计数器的异常,来发现引起闪退的异常文字。在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。
这就需要一个性能非常高的通用 key-value 存储组件,我们考察了 SharedPreferences、NSUserDefaults、SQLite 等常见组件,发现都没能满足如此苛刻的性能要求。考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件。
3、MMKV 原理
内存准备:
通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
数据组织:
数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。
写入优化:
考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。
空间增长:
使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。
更详细的设计原理参考MMKV 原理。
4、iOS 指南
安装引入(推荐使用 CocoaPods):
安装CocoaPods;
打开命令行,cd到你的项目工程目录, 输入pod repo update让 CocoaPods 感知最新的 MMKV 版本;
打开 Podfile, 添加pod 'MMKV'到你的 app target 里面;
在命令行输入pod install;
用 Xcode 打开由 CocoaPods 自动生成的.xcworkspace文件;
添加头文件#import <MMKV/MMKV.h>,就可以愉快地开始你的 MMKV 之旅了。
更多安装指引参考iOS Setup。
快速上手:
MMKV 的使用非常简单,无需任何配置,所有变更立马生效,无需调用synchronize:
MMKV *mmkv = [MMKV defaultMMKV]; [mmkvsetBool:YESforKey:@"bool"];BOOL bValue = [mmkvgetBoolForKey:@"bool"]; [mmkvsetInt32:-1024forKey:@"int32"];int32_t iValue = [mmkvgetInt32ForKey:@"int32"]; [mmkvsetObject:@"hello, mmkv"forKey:@"string"];NSString *str = [mmkvgetObjectOfClass:NSString.classforKey:@"string"];
更详细的使用教程参考iOS Tutorial。
性能对比:
循环写入随机的int1w 次,我们有如下性能对比:
更详细的性能对比参考iOS Benchmark。
5、Android 指南
安装引入:
推荐使用 Maven:
dependencies{implementation'com.tencent:mmkv:1.0.10'// replace"1.0.10"with any available version}
更多安装指引参考Android Setup。
快速上手:
MMKV 的使用非常简单,所有变更立马生效,无需调用sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 MainActivity 里:
protectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); String rootDir = MMKV.initialize(this); System.out.println("mmkv root: "+ rootDir);//……}
MMKV 提供一个全局的实例,可以直接使用:
importcom.tencent.mmkv.MMKV;//……MMKV kv = MMKV.defaultMMKV();kv.encode("bool",true);booleanbValue = kv.decodeBool("bool");kv.encode("int", Integer.MIN_VALUE);intiValue = kv.decodeInt("int");kv.encode("string","Hello from mmkv");String str = kv.decodeString("string");
MMKV 支持多进程访问,更详细的用法参考Android Tutorial。
性能对比:
循环写入随机的int1k 次,我们有如下性能对比:
更详细的性能对比参考Android Benchmark。
微信自用高性能通用key-value组件MMKV已开源!的更多相关文章
- 微信团队分享:iOS版微信的高性能通用key-value组件技术实践
本文来自微信开发团队guoling的技术分享. 1.前言 本文要分享的是iOS版微信内部正在推广和使用的一个高性能通用key-value 组件的技术实践过程,该组件在微信内部被命名为MMKV(以下简称 ...
- 腾讯开源 MMKV — 基于mmap的高性能通用key-value组件
一.介绍 MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强.从 2015 年中至今,在 iOS 微信上使用已有近 3 ...
- 如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
1.前言 关于微信内部正在使用的网络层封装库Mars开源的消息,1个多月前就已满天飞(参见<微信Mars:微信内部正在使用的网络层封装库,即将开源>),不过微信团队没有失约,微信Mars ...
- 【转】如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
网上看到关于微信官方的跨平台跨业务的终端基础组件Mars的介绍文章,转载这这里.源代码: https://github.com/Tencent/mars作者:男人链接:https://zhuanlan ...
- 超轻量级高性能ORM数据访问组件Deft,比dapper快20%以上
超轻量级高性能ORM数据访问组件Deft,比dapper快20%以上 阅读目录 Deft简介 Deft 核心类介绍 Deft 3分钟即可上手使用 其他可选的配置参数 性能测试 Demo代码下载 回到顶 ...
- Redis 学习(一) —— 安装、通用key操作命令
一.Redis介绍 1.介绍 通常,在系统中,我们会把数据交由数据库来存储,但传统的数据库增删查改的性能较差,且比较复杂.根据 80/20 法则,百分之八十的业务访问集中在百分之二十的数据上.是否可以 ...
- day37 爬虫2(web微信、高性能相关、Scrapy)
s16day37 爬虫2 参考博客:http://www.cnblogs.com/wupeiqi/articles/6229292.html 课堂代码:https://github.com/liyon ...
- 微信小程序wx:key以及wx:key=" *this"详解:
今天写微信小程序无意中看到控制台给出了这样一行提示: 求解百度才知道,给大家分享一下: 1.wx:for定义 官方文档:在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲 ...
- 微信小程序 基本介绍及组件
创建项目 微信开发工具深入介绍 https://developers.weixin.qq.com/miniprogram/dev/devtools/devtools.html 基本项目目录 1. 配置 ...
随机推荐
- docker mysql 主主同步
转发自:https://blog.csdn.net/money9sun/article/details/85099134 第一步:安装docker https://www.cnblogs.com/ ...
- spring Mongodb查询索引报错 java.lang.NumberFormatException: empty String
最近事情比较多,本篇文章算是把遇到的问题杂糅到一起了. 背景:笔者最近在写一个mongo查询小程序,由于建立索引时字段名用大写,而查询的时候用小写. 代码如下: db.getCollection(&q ...
- leetcode26: 删除排序数组中的重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...
- 1、背景介绍及移动云MAS平台 --短信平台
目的: 刚开发完成一套短信平台以及一个Web端短信发送系统,短信平台耗时两个周.短信发送系统耗时两个多月,开发使用的技术没什么高科技含量,在此主要是记录下很多情况的处理方案,希望能让大家提出改善方案和 ...
- github上用golang写的项目
1.moby/moby docker的新马甲 2.kubernetes/kubernetes 分布式容器管理 3.grafana/grafana 一个可视化面板,有漂亮的仪表盘,多种数据来源,适合做系 ...
- win10无法访问服务器上的共享文件夹怎么设置,提示:你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问
此问题需要修改Win10 网络策略 按window+R键输入gpedit.msc 来启动本地组策略编辑器. 依次找到“计算机配置-管理模板-网络-Lanman工作站”这个节点,在右侧内容区可以看到“启 ...
- Docker 镜像使用
当运行容器是,使用的镜像如果在本地中不存在,docker就会自动从docker镜像仓库中下载,默认是从Docker Hub 公共镜像源下载. 下面我们来学习: 1.管理和使用本地Docker主机镜像 ...
- java学习(一)
目录 java简介 java基础 基本语法 java标识符 java变量 变量类型 变量声明 java常量 Java 基本数据类型 内置数据类型 引用数据类型 Java类型转换 java注释 操作符 ...
- mysql中的concat函数,concat_ws函数,concat_group函数之间的区别
一.CONCAT()函数CONCAT()函数用于将多个字符串连接成一个字符串.使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为+----+ ...
- 关于Visual Studio调试C/C++,JS,PHP,JAVA,Python等语言的方法
我在开始接触vs code后,确实对它的高颜值和小巧灵活而着迷,但是有一个非常现实的问题,相对于vs来说,vscode是一个代码编辑器,而不是一个IDE,在代码编译运行上存在着极大的问题,尤其是开始编 ...