冲突解决规则

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

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

  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 对象的内容:

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" ]}