主动-主动数据库中的 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 文档进行并发更新,并允许合并结果。

冲突解决规则

使用主动-主动数据库,两个不同的实例可以尝试同时对同一数据运行写入作。如果发生这种情况,则当副本尝试将这些更改彼此同步时,可能会发生冲突。冲突解决规则确定数据库如何处理冲突作。

有两种类型的冲突解决方式:

  1. 合并:

    • 这些作是 Associative 的。

    • 合并两个作的结果。

  2. 赢取:

    • 这些作不是 association 的。

    • 一个作赢得冲突并设置值。

    • 忽略丢失的作。

以下冲突解决规则显示了主动-主动数据库如何解决各种 JSON 命令的冲突。

为键分配不同类型的键

冲突

两个实例同时将不同类型的值分配给 JSON 文档中的同一键。

例如:

实例 1 将对象分配给 JSON 文档中的键。

实例 2 将数组分配给相同的键。

分辨率类型

解决规则

具有较小 ID 的实例获胜,因此在给定示例中,键将成为对象。

时间 描述 实例 1 实例 2
T1 为对象或数组设置相同的键 JSON 的 JSON 格式。SET 文档 $.a '{}' JSON 的 JSON 格式。SET 文档 $.a '[]'
T2 向对象和数组添加数据 JSON 的 JSON 格式。SET 文档 $.a.x '“y”'

结果:
{“a”: {“x”: “y”}}
JSON 的 JSON 格式。SET 文档 $.a '[“z”]'

结果:
{“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 文档 JSON 的 JSON 格式。SET 文档 $ '{“field”: “a”}' JSON 的 JSON 格式。SET 文档 $ '{“field”: “b”}'
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 更新现有文档 JSON 的 JSON 格式。SET 文档 $ '{“field2”: “value2”}' JSON 的 JSON 格式。SET 文档 $.field1 '[1, 2, 3]'
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 文档 JSON 的 JSON 格式。SET 文档 $ '{“field1”: “value2”}'
T3 主动-主动同步 –同步– –同步–
T4 实例 2 获胜 JSON 的 JSON 格式。GET 文档 $

结果:
{“field1”: “value2”}
JSON 的 JSON 格式。GET 文档 $

结果:
{“field1”: “value2”}

删除与更新

冲突

实例 1 删除了 JSON 文档JSON.DEL.

实例 2 使用JSON.SET.

分辨率类型

解决规则

文档删除胜于更新。

时间 描述 实例 1 实例 2
T1 文档在两个实例上都存在 JSON 的 JSON 格式。GET doc $

结果:
{“field1”: “value1”}
JSON 的 JSON 格式。GET doc $

结果:
{“field1”: “value1”}
T2 实例 1 删除文档;实例 2 会更新它 JSON 的 JSON 格式。DEL 文档 JSON 的 JSON 格式。SET 文档 $.field1 '[1, 2, 3]'
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 使用不同的数据更新同一字段 JSON 的 JSON 格式。SET 文档 $.field “b” JSON 的 JSON 格式。SET 文档 $.field “c”
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" ]}
RATE THIS PAGE
Back to top ↑