微信自用高性能通用key-value組件MMKV已開源!

一、MMKV簡介

騰訊微信團隊於2018年9月底宣佈開源 MMKV ,這是基於 mmap 內存映射的 key-value 組件,底層序列化/反序列化使用 protobuf 實現,主打高性能和穩定性。近期也已移植到 Android 平臺,一併對外開源。html

MMKV 是基於 mmap 內存映射的 key-value 組件,底層序列化/反序列化使用 protobuf 實現,性能高,穩定性強。從 2015 年中至今,在 iOS 微信上使用已有近 3 年,其性能和穩定性通過了時間的驗證。近期也已移植到 Android 平臺,一併開源。android

MMKV最新源碼託管地址:https://github.com/Tencent/MMKVgit

二、MMKV 源起

在微信客戶端的平常運營中,時不時就會爆發特殊文字引發系統的 crash(請參見文章:《微信團隊分享:iOS版微信是如何防止特殊字符致使的炸羣、APP崩潰的?》、《微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐》),文章裏面設計的技術方案是在關鍵代碼先後進行計數器的加減,經過檢查計數器的異常,來發現引發閃退的異常文字。在會話列表、會話界面等有大量 cell 的地方,但願新加的計時器不會影響滑動性能;另外這些計數器還要永久存儲下來——由於閃退隨時可能發生。github

這就須要一個性能很是高的通用 key-value 存儲組件,咱們考察了 SharedPreferences、NSUserDefaults、SQLite 等常見組件,發現都沒能知足如此苛刻的性能要求。考慮到這個防 crash 方案最主要的訴求仍是實時寫入,而 mmap 內存映射文件恰好知足這種需求,咱們嘗試經過它來實現一套 key-value 組件。微信

三、MMKV 原理

內存準備:app

經過 mmap 內存映射文件,提供一段可供隨時寫入的內存塊,App 只管往裏面寫數據,由操做系統負責將內存回寫到文件,沒必要擔憂 crash 致使數據丟失。ide

數據組織:性能

數據序列化方面咱們選用 protobuf 協議,pb 在性能和空間佔用上都有不錯的表現。優化

寫入優化:ui

考慮到主要使用場景是頻繁地進行寫入更新,咱們須要有增量更新的能力。咱們考慮將增量 kv 對象序列化後,append 到內存末尾。

空間增加:

使用 append 實現增量更新帶來了一個新的問題,就是不斷 append 的話,文件大小會增加得不可控。咱們須要在性能和空間上作個折中。

更詳細的設計原理參考MMKV 原理

四、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

五、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

相關文章
相關標籤/搜索