主动-主动数据库中的 JSON
有关将 JSON 与主动-主动数据库结合使用的信息。
Redis 企业软件 | Redis 云 |
---|
主动-主动数据库支持 JSON 数据结构。
该设计基于 Kleppmann 和 Beresford 的 A Conflict-Free Replicated JSON Datatype,但实现包括一些更改。本文还改编了几个冲突解决规则示例。
先决条件
要在主动-主动数据库中使用 JSON,您必须在数据库创建期间启用 JSON。
主动-主动 Redis Cloud 数据库默认添加 JSON。有关详细信息,请参阅 Redis Cloud 文档中的创建主动-主动订阅。
在 Redis Enterprise Software 中,默认情况下不为主动-主动数据库启用 JSON。有关说明,请参阅 Redis 堆栈和 Redis Enterprise 文档中的创建主动-主动 JSON 数据库。
命令差异
某些 JSON 命令对主动-主动数据库的工作方式不同。
JSON.CLEAR
JSON.CLEAR
重置 JSON 数组和对象。它支持从主动-主动数据库中的不同实例对 JSON 文档进行并发更新,并允许合并结果。
冲突解决规则
使用主动-主动数据库,两个不同的实例可以尝试同时对同一数据运行写入作。如果发生这种情况,则当副本尝试将这些更改彼此同步时,可能会发生冲突。冲突解决规则确定数据库如何处理冲突作。
有两种类型的冲突解决方式:
-
合并:
-
这些作是 Associative 的。
-
合并两个作的结果。
-
-
赢取:
-
这些作不是 association 的。
-
一个作赢得冲突并设置值。
-
忽略丢失的作。
-
以下冲突解决规则显示了主动-主动数据库如何解决各种 JSON 命令的冲突。
为键分配不同类型的键
冲突
两个实例同时将不同类型的值分配给 JSON 文档中的同一键。
例如:
实例 1 将对象分配给 JSON 文档中的键。
实例 2 将数组分配给相同的键。
分辨率类型
赢
解决规则
具有较小 ID 的实例获胜,因此在给定示例中,键将成为对象。
例
时间 | 描述 | 实例 1 | 实例 2 |
---|---|---|---|
T1 | 为对象或数组设置相同的键 | JSON 的 JSON 格式。SET 文档 $.a '{}' | JSON 的 JSON 格式。SET 文档 $.a '[]' |
T2 | 向对象和数组添加数据 | 结果: {“a”: {“x”: “y”}} |
结果: {“a”: [“z”]} |
T3 | 主动-主动同步 | –同步– | –同步– |
T4 | 实例 1 获胜 | JSON 的 JSON 格式。GET 文档 $ 结果: {“a”: {“x”: “y”}} |
JSON 的 JSON 格式。GET 文档 $ 结果: {“a”: {“x”: “y”}} |
Create 与 Create
冲突
两个实例同时使用JSON.SET
将新的 JSON 文档分配给同一键。
分辨率类型
赢
解决规则
ID 较小的实例获胜。
例
时间 | 描述 | 实例 1 | 实例 2 |
---|---|---|---|
T1 | 创建新的 JSON 文档 | ||
T2 | 主动-主动同步 | –同步– | –同步– |
T3 | 实例 1 获胜 | JSON 的 JSON 格式。GET doc $ 结果: {“field”: “a”} |
JSON 的 JSON 格式。GET doc $ 结果: {“field”: “a”} |
创建与更新
冲突
实例 1 创建一个新文档,并使用JSON.SET
.
实例 2 使用JSON.SET
.
分辨率类型
赢
解决规则
创建新文档的作胜出。
例
时间 | 描述 | 实例 1 | 实例 2 |
---|---|---|---|
T1 | 文档在两个实例上都存在 | JSON 的 JSON 格式。GET doc $ 结果: {“field1”: “value1”} |
JSON 的 JSON 格式。GET doc $ 结果: {“field1”: “value1”} |
T2 | 实例 1 创建一个新文档;实例 2 更新现有文档 | ||
T3 | 主动-主动同步 | –同步– | –同步– |
T4 | 实例 1 获胜 | JSON 的 JSON 格式。GET 文档 . 结果: {“field2”: “value2”} |
JSON 的 JSON 格式。GET 文档 . 结果: {“field2”: “value2”} |
Delete 与 create
冲突
实例 1 删除了 JSON 文档JSON.DEL
.
实例 2 使用JSON.SET
创建新的 JSON 文档并将其分配给实例 1 删除的键。
分辨率类型
赢
解决规则
文档创建胜于删除。
例
时间 | 描述 | 实例 1 | 实例 2 |
---|---|---|---|
T1 | 文档在两个实例上都存在 | JSON 的 JSON 格式。GET doc $ 结果: {“field1”: “value1”} |
JSON 的 JSON 格式。GET doc $ 结果: {“field1”: “value1”} |
T2 | 实例 1 删除文档;实例 2 创建新文档 | JSON 的 JSON 格式。DEL 文档 | |
T3 | 主动-主动同步 | –同步– | –同步– |
T4 | 实例 2 获胜 | JSON 的 JSON 格式。GET 文档 $ 结果: |
JSON 的 JSON 格式。GET 文档 $ 结果: {“field1”: “value2”} |
删除与更新
冲突
实例 1 删除了 JSON 文档JSON.DEL
.
实例 2 使用JSON.SET
.
分辨率类型
赢
解决规则
文档删除胜于更新。
例
时间 | 描述 | 实例 1 | 实例 2 |
---|---|---|---|
T1 | 文档在两个实例上都存在 | JSON 的 JSON 格式。GET doc $ 结果: |
JSON 的 JSON 格式。GET doc $ 结果: {“field1”: “value1”} |
T2 | 实例 1 删除文档;实例 2 会更新它 | JSON 的 JSON 格式。DEL 文档 | |
T3 | 主动-主动同步 | –同步– | –同步– |
T4 | 实例 1 获胜 | JSON 的 JSON 格式。GET doc $ 结果: (nil) |
JSON 的 JSON 格式。GET doc $ 结果: (nil) |
更新与更新
冲突
实例 1 使用JSON.SET
.
实例 2 使用不同的值更新同一字段。
分辨率类型
赢
解决规则
ID 最小的实例获胜。
例
时间 | 描述 | 实例 1 | 实例 2 |
---|---|---|---|
T1 | 文档在两个实例上都存在 | JSON 的 JSON 格式。GET doc $ 结果: {“field”: “a”} |
JSON 的 JSON 格式。GET doc $ 结果: {“field”: “a”} |
T2 | 使用不同的数据更新同一字段 | ||
T3 | 主动-主动同步 | –同步– | –同步– |
T4 | 实例 1 获胜 | JSON 的 JSON 格式。GET doc $ 结果: {“field”: “b”} |
JSON 的 JSON 格式。GET doc $ 结果: {“field”: “b”} |
更新与清除
v2.2 之前的 RedisJSON 版本有两种不同的方法来重置 JSON 对象的内容:
-
分配一个新的空 JSON 对象:
JSON.SET doc $.colors '{}'
If you use this method, it cannot be merged with a concurrent update.
-
For each key, remove it with
JSON.DEL
:JSON.DEL doc $.colors.blue
With this method, it can merge the reset with concurrent updates.
As of RedisJSON v2.2, you can use the JSON.CLEAR
command to reset the JSON document without removing each key manually. This method also lets concurrent updates be merged.
Assign an empty object
Conflict
Instance 1 adds "red" to the existing "colors" object with JSON.SET
.
Instance 2 assigns a new empty object for "colors".
Resolution type
Win over
Resolution rule
Document creation wins over the update, so the result will be an empty object.
Example
Time
Description
Instance 1
Instance 2
t1
The document exists on both instances
JSON.GET doc $
Result:
{"colors": {"blue": "#0000ff"}}
JSON.GET doc $
Result:
{"colors": {"blue": "#0000ff"}}
t2
Instance 1 adds a new color; instance 2 resets colors to an empty object
JSON.SET doc $.colors.red ‘#ff0000’
JSON.SET doc $.colors ‘{}’
t3
Instance 2 adds a new color
JSON.SET doc $.colors.green ‘#00ff00’
t4
JSON.GET doc $
Result:
{"colors": {"blue": "#0000ff", "red": "#ff0000"}}
JSON.GET doc $
Result:
{"colors": {"green": "#00ff00"}}
t5
Active-Active synchronization
– Sync –
– Sync –
t6
Instance 2 wins
JSON.GET doc $
Result:
{"colors": {"green": "#00ff00"}}
JSON.GET doc $
Result:
{"colors": {"green": "#00ff00"}}
Use JSON.CLEAR
Conflict
Instance 1 adds "red" to the existing "colors" object with JSON.SET
.
Instance 2 clears the "colors" object with JSON.CLEAR
and adds "green" to "colors".
Resolution type
Merge
Resolution rule
Merges the results of all operations.
Example
Time
Description
Instance 1
Instance 2
t1
The document exists on both instances
JSON.GET doc $
Result:
{"colors": {"blue": "#0000ff"}}
JSON.GET doc $
Result:
{"colors": {"blue": "#0000ff"}}
t2
Instance 1 adds a new color; instance 2 resets the colors
JSON.SET doc $.colors.red ‘#ff0000’
JSON.CLEAR doc $.colors
t3
JSON.GET doc $
Result:
{"colors": {"blue": "#0000ff", "red": "#ff0000"}}
JSON.GET doc $
Result:
{"colors": {}}
t4
Instance 2 adds a new color
JSON.SET doc $.colors.green ‘#00ff00’
t5
JSON.GET doc $
Result:
{"colors": {"green": "#00ff00"}}
t6
Active-Active synchronization
– Sync –
– Sync –
t7
Merges the results of both instances
JSON.GET doc $
Result:
{"colors": {"red": "#ff0000", "green": "#00ff00"}}
JSON.GET doc $
Result:
{"colors": {"red": "#ff0000", "green": "#00ff00"}}
Update versus update array
Conflict
Two instances update the same existing array with different content.
Resolution type
Merge
Resolution rule
Merges the results of all operations on the array. Preserves the original element order from each instance.
Example
Time
Description
Instance 1
Instance 2
t1
The document exists on both instances
JSON.GET doc $
Result:
'["a", "b", "c"]'
JSON.GET doc $
Result:
'["a", "b", "c"]'
t2
Instance 1 removes an array element; instance 2 adds one
JSON.ARRPOP doc $ 1
Result:
["a", "c"]
JSON.ARRINSERT doc $ 0 ‘“y”’
Result:
["y", "a", "b", "c"]
t3
Both instances add another element to the array
JSON.ARRINSERT doc $ 1 ‘“x”’
Result:
["a", "x", "c"]
JSON.ARRINSERT doc $ 2 ‘“z”’
Result:
["y", "a", "z", "b", "c"]
t4
Active-Active synchronization
– Sync –
– Sync –
t5
Merge results from both instances
JSON.GET doc $
Result:
["y", "a", "x", "z", "c"]
JSON.GET doc $
Result:
["y", "a", "x", "z", "c"]
Update versus delete array element
Conflict
Instance 1 removes an element from a JSON array with JSON.ARRPOP
.
Instance 2 updates the same element that instance 1 removes.
Resolution type
Win over
Resolution rule
Deletion wins over updates.
Example
Time
Description
Instance 1
Instance 2
t1
The document exists on both instances
JSON.GET doc $
Result:
{“todo”: [{“title”: “buy milk”, “done”: false}]}
JSON.GET doc $
Result:
{“todo”: [{“title”: “buy milk”, “done”: false}]}
t2
Instance 1 removes an array element; instance 2 updates the same element
JSON.ARRPOP doc $.todo 0
JSON.SET doc '$.todo[0]["done"]' 'true'’
t3
JSON.GET doc $
Result:
{“todo”: []}
JSON.GET doc $
Result:
[{“title”: “buy milk”, “done”: true}]}
t4
Active-Active synchronization
– Sync –
– Sync –
t5
Instance 1 wins
JSON.GET doc $
Result:
doc = {“todo”: []}
JSON.GET doc $
Result:
doc = {“todo”: []}
Update versus update object
Conflict
Both instances update the same existing object with different content.
Resolution type
Merge
Resolution rule
Merges the results of all operations on the object.
Example
Time
Description
Instance 1
Instance 2
t1
The document exists on both instances
JSON.GET doc $
Result:
'{"grocery": []}'
JSON.GET doc $
Result:
'{"grocery": []}'
t2
Add new elements to the array
JSON.ARRAPPEND doc $.grocery ‘“eggs”’
JSON.ARRAPPEND doc $.grocery ‘“milk”’
t3
Add new elements to the array
JSON.ARRAPPEND doc $.grocery ‘“ham”’
JSON.ARRAPPEND doc $.grocery ‘“flour”’
t4
JSON.GET doc $
Result:
{"grocery":["eggs", "ham"]}
JSON.GET doc $
Result:
{"grocery":["milk", "flour"]}
t5
Active-Active synchronization
– Sync –
– Sync –
t6
Merges the results from both instances
JSON.GET doc .
Result:
{"grocery":["eggs","ham","milk", "flour"]}
JSON.GET doc .
Result:
{"grocery":["eggs","ham","milk", "flour" ]}
On this page