将 JSON 存储在主动-主动数据库中

主动-主动数据库的 JSON 支持和冲突解决规则。

Redis 堆栈

RedisJSON v2.2 在主动-主动 Redis Enterprise 数据库中增加了对 JSON 的支持。

该设计基于 Kleppmann 和 Beresford 的 A Conflict-Free Replicated JSON Datatype,但实现包括一些更改。本文还改编了几个冲突解决规则示例。

创建主动-主动 JSON 数据库

要在主动-主动数据库中使用 JSON,您必须在数据库创建期间启用 JSON。

主动-主动 Redis Cloud 数据库默认添加 JSON。有关详细信息,请参阅 Redis Cloud 文档中的创建主动-主动数据库

在 Redis Enterprise Software 中,默认情况下不为主动-主动数据库启用 JSON。要在 Redis Enterprise Software 中创建主动-主动 JSON 数据库,请执行以下作:

  1. 有关先决条件和详细步骤,请参阅 Redis Enterprise Software 文档中的创建主动-主动异地复制数据库

  2. Create Active-Active database 屏幕的 Capabilities 部分中,选择 JSON:

    从 Capabilities 部分选择 JSON。
    注意:
    当您选择 JSON 时,默认情况下还会选择 Search 和 Query,以允许您为 JSON 文档编制索引和查询。如果您不想使用这些附加功能,可以清除 Search and Query (搜索和查询) 复选框。
  3. 配置其他数据库设置。

  4. 选择 创建

命令差异

某些 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 ↑