
想了解更多内容,请访问:
51CTO和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com
1 简介本文基于OpenHarmonyOS 3.0 LTS 来讲解分布式数据服务(Distributed Data Service,DDS) 提供不同设备间数据库数据分布式的能力。从架构上来说,分布式数据服务是开源鸿蒙底层服务的基础服务,与分布式任务调度同层。然而在使用分布式任务调度功能时,基本上都需要进一步要求数据交互功能,完成完整的分布式功能,因此在学习分布式任务调度的同时,不可避免的需要学习分布式数据服务相关的功能与底层服务。
本文在写作时,调试JS的DEMO时发现了更底层的方舟JS运行层的BUG,提交了ISSUE,并试图提交了PR。如果大家在运行DEMO时发现问题,请先尝试合并上述PR并重新全部编译系统并刷机再试。
1.1 分布式相关《OpenHarmony 源码解析之分布式任务调度》 《OpenHarmony 源码解析之分布式数据库》 1.2 OpenHarmony架构图

先看开源鸿蒙官方文档对分布式数据服务的描述:
分布式数据服务(Distributed Data Service,DDS) 提供不同设备间数据库数据分布式的能力。通过结合帐号、应用和数据库三元组,分布式数据服务对数据进行隔离。在通过可信认证的设备间,分布式数据服务支持数据相互同步,为用户提供在多种终端设备上一致的数据访问体验。
目前开源鸿蒙还没有整合账号功能,因此测试的时候账号可以自由选择,填写一致即可。应用和数据库则必须保持一致,才能进行完整的分布式数据数据隔离,提供数据在多种终端设备上一致的访问体验。
2.2 源码结构2.3 分布式数据服务架构设计图
- ├── BUILD.gn ├── figures
- │ ├── en-us_image_0000001162536643.png │ └── zh-cn_image_0000001162536643.png
- ├── frameworks │ ├── innerkitsimpl
- │ │ └── distributeddatafwk # 框架层实现 │ │ ├── include
- │ │ ├── src │ │ └── test
- │ └── jskitsimpl │ └── distributeddata # JS接口实现
- │ ├── include │ └── src
- ├── interfaces │ ├── innerkits # 内部接口,主要是头文件
- │ │ ├── app_distributeddata │ │ │ ├── BUILD.gn
- │ │ │ └── include │ │ └── distributeddata
- │ │ ├── BUILD.gn │ │ └── include
- │ └── jskits # JS接口,BUILD用 │ └── distributeddata
- │ └── BUILD.gn ├── LICENSE
- ├── OAT.xml ├── ohos.build
- ├── README.md ├── README_zh.md
- ├── services │ └── distributeddataservice
- │ ├── adapter # 适配实现 │ │ ├── account # 账号适配
- │ │ ├── autils # 实用库,包括任务、线程、目录等 │ │ ├── broadcaster # 发送广播
- │ │ ├── BUILD.gn │ │ ├── communicator # 通讯适配
- │ │ ├── dfx # 日志、统计、错误等相关处理 │ │ ├── include
- │ │ ├── LICENSE │ │ ├── permission # 权限
- │ │ ├── security # 安全相关 │ │ ├── test
- │ │ └── utils │ ├── app # 用户程序实现
- │ ├── libs │ │ └── distributeddb
- │ │ ├── BUILD.gn │ │ ├── common
- │ │ ├── communicator # 设备间通讯 │ │ ├── include
- │ │ ├── interfaces │ │ ├── storage # 存储实现,包括单版本KV、多版本KV、SQLITE3等
- │ │ ├── syncer # 同步 │ │ └── test
- │ ├── sa_profile │ └── test
- └── test

官方文档是这么描述的:
通过调用分布式数据服务接口实现分布式数据库创建、访问、订阅功能,服务接口通过操作服务组件提供的能力,将数据存储至存储组件,存储组件调用同步组件实现将数据同步,同步组件使用通信适配层将数据同步至远端设备,远端设备通过同步组件接收数据,并更新至本端存储组件。
2.5 分布式数据最终一致性:是指某一设备成功增、删、改数据后,组网内设备可能读取不到本次更新数据,但在某个时间窗口之后组网内设备的数据能够达到一致状态。
强一致性对分布式数据的管理要求非常高,在服务器的分布式场景可能会遇到。因为移动终端设备的不常在线、以及无中心的特性,分布式数据服务不支持强一致,只支持最终一致性。
目前分布式数据的数据模型仅支持KV数据模型,不支持外键、触发器等关系型数据库中的技术点。虽然开源鸿蒙底层支持基于SQLITE3的关系型数据库,但是并不在分布式数据层面支持。
当前KV数据模型的限制:
设备协同数据库,Key最大支持896Byte,Value最大支持4MB。 单版本数据库,Key最大支持1KB,Value最大支持4MB。 每个程序最多支持同时打开16个DB。 当前流控机制针对KvStore的接口1秒最大访问1000次,1分钟最大访问10000次。 KvManager的接口1秒最大访问50次,1分钟最大访问500次。 2.6 使用前提
从开源鸿蒙的分布式数据源代码中,可以看到目前只有手机(phone)、穿戴式设备(wearable)、车载系统(ivi)会搭载,其它更轻量的设备可能暂时不支持,或者需要剪裁定制支持。
目前在两台标准设备的开源系统鸿蒙上,是默认集成了该功能,可以直接使用的。
开源鸿蒙的分布式数据如果只在单机使用,那么无需前提条件。如果需要其分布式功能,那么就需要设备之间完成组网;而组网的前提条件是完成设备认证。具体步骤,请参考OpenHarmony 源码解析之分布式任务调度。
3 编程接口 3.1 导入模块
- import distributedData from '@ohos.data.distributedData';
下面各个接口大多有callback和promise两种异步方式,本文均以promise方式为例,callback方式大同小异,请自行查阅文档。
3.2 创建管理器
- distributedData.createKVManager createKVManager(config: KVManagerConfig, callback: AsyncCallback
): void - createKVManager(config: KVManagerConfig): Promise
创建一个KVManager对象实例,用于管理数据库对象,并通过Promise方式返回,此方法为异步方法。
示例:
3.3 获取存储实例
- let kvManager; try {
- const kvManagerConfig = { bundleName : 'com.example.datamanagertest',
- userInfo : { userId : '0',
- userType : 0 }
- } distributedData.createKVManager(kvManagerConfig).then((manager) => {
- console.log("createKVManager success"); kvManager = manager;
- }).catch((err) => { console.log("createKVManager err: " + JSON.stringify(err));
- }); } catch (e) {
- console.log("An unexpected error occurred. Error:" + e); }
- kvManager.getKVStore getKVStore
(storeId: string, options: Options): Promise
通过指定Options和storeId,创建并获取KVStore数据库,并通过Promise方式返回,此方法为异步方法。
示例:
3.4 存、取、删除、同步
- let kvStore; try {
- const options = { createIfMissing : true,
- encrypt : false, backup : false,
- autoSync : true, //手动同步、自动同步 kvStoreType : 1, //当前只能使用0(默认):表示多设备协同数据库,1:单版本数据库
- securityLevel : 3, };
- kvManager.getKVStore('storeId', options).then((store) => { console.log("getKVStore success");
- kvStore = store; }).catch((err) => {
- console.log("getKVStore err: " + JSON.stringify(err)); });
- } catch (e) { console.log("An unexpected error occurred. Error:" + e);
- }
3.5 注册事件通知回调
- kvStore.put(key: string, value: Uint8Array | string | number | boolean): Promise
kvStore.get(key: string): Promise - kvStore.delete(key: string): Promise
kvStore.sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: number): void
SubscribeType 描述订阅类型。
0: SUBSCRIBE_TYPE_LOCAL 表示订阅本地数据变更。 1: SUBSCRIBE_TYPE_REMOTE 表示订阅远端数据变更。 2: SUBSCRIBE_TYPE_ALL 表示订阅远端和本地数据变更。
4 小结
- kvStore.on(event: 'dataChange', type: SubscribeType, observer: Callback
): void kvStore.on(event: 'syncComplete', syncCallback: Callback>): void
以上步骤,均已在DevEco Studio 3.0.0.600 x64中编写成功,并且在两台Hi3516D设备间成功运行,附代码(分布式任务调度和分布式数据测试.zip)。
再次提醒,分布式数据底层依赖ARK JS引擎,目前发现字符串处理有BUG,如运行出现问题,请先合并PR,然后重新编译全系统并刷机后再运行DEMO。
想了解更多内容,请访问:
51CTO和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com