【问题标题】:Lock file for update one section of data or all the file content锁定文件以更新一段数据或所有文件内容
【发布时间】:2019-05-02 07:35:52
【问题描述】:

我有可以从多个进程更新的文件,因此我想使用锁定并找到 https://github.com/gofrs/flock 这可能会有所帮助

但我认为这个问题有点复杂,例如更新 api 需要 read 之前的 file/ 部分的文件(我们提供 api 来读取 fileapplicationname 的对象)
获取json数据在内存中修改并更新文件。

有两种选择:

  1. 更新所有文件内容
  2. 更新文件的部分,即一个 应用程序属性

问题如下:


 1. Process A & Process B (can be more…) Reads the object  of
    application name  `node1`

 2. Process A update the section (node1) with new data (for example
        change the kind property and update)

 3. Process B want to do the same , the problem is that between the time
        it reads the data and the time it wants to update ,the data is not
        valid since other process already update it.

此外,相同的场景对所有文件上下文都有效

Race 条件问题...

这是一些stateless 进程可以在任何给定时间更新的文件的简短示例

ID: demo
version: 0.0.1

applications:
 - name: node1
   kind: html5
   path: node1
   expose:
    - name: node_api
      properties:
         url: ${app-url}


 - name: node2
   kind: nodejs
   path: node2
   parameters:
      quota: 256M
      memory: 256M

我们如何克服这个问题,或者简化它以避免竞争条件和串通?

【问题讨论】:

  • 进程读取文件时,会一直更新文件内容吗?
  • @AnkitDeshpande - 并不总是...
  • 听起来你真的很想使用数据库。
  • @flyx - 抱歉,在这种情况下我不能,我还有其他选择吗?甚至是简化事情的方法?或限制 API...我对想法持开放态度...
  • 当进程 B 尝试将数据写入文件并看到它已被进程 A 更新时,进程 B 应该做什么?

标签: go locking race-condition file-locking


【解决方案1】:

这是一个常见问题,因此请寻找已知的解决方案。例如,乐观锁定。

类似这样的伪代码:

lock file for read
read file into data1
release file lock
hash data1 as hash1
update data1
lock file for update
read file into data2
hash data2 as hash2
if hash1 != hash2
    release file lock
    return error
write file from (updated) data1
release file lock
return success

【讨论】:

  • 谢谢,1. 我应该把哈希数据保存在哪里? 2. 为什么我需要write updated data #1 步骤,它已经在第 5 行完成了?
  • 第 5 行内存数据被更新。在验证文件的哈希值没有改变后,你在后面的行中将它写入文件
【解决方案2】:

我在 cmets 中的建议仍然有效:您描述的用例通常由数据库实现。它们旨在解决这个问题。

但是,如果你使用这个 YAML 文件,你可以像这样实现你的写入操作:

  1. 创建一个锁。
  2. 通过读取文件更新
  3. 在内存中执行更改。
  4. 写回文件。
  5. 释放锁。

这确保不会更新陈旧的数据。

【讨论】:

    【解决方案3】:

    可以有多种方法来解决这个问题。

    1)使用锁
    您可以创建读写锁。如果一个进程只想读取一个文件,它可以获取一个读锁。如果一个进程要写,它会获得一个写锁,其他进程必须等到写锁被释放。

    使用版本控制
    您可以保留一个跟踪版本的计数器。 在写入文件的方法中仍然需要锁定。

    初始版本 1.
    进程 B 读取文件,查看版本 1。
    进程 A 读取文件,查看版本 1,然后写入将版本增加到 2,然后更新文件。
    所以现在写之前的流程B会比较版本。由于它的版本(版本 1)低于当前版本(版本 2),它将不得不中止/重试其操作。

    仅当文件的内容与其读取的内容相同时,该进程才应更新文件。您可以按照 peterSO 在他的回答中建议的方式实现它。

    【讨论】:

    • 读写锁不能防止过时的数据。这个概念在这里并不适用,因为所有读取数据的进程都将其复制到内存数据结构中。要么为这些进程中的每一个创建一个读锁——在这种情况下,只要其他进程拥有一个副本(这听起来没什么用),你就不能写入数据——或者你没有,在这种情况下你没有解决不了问题。
    猜你喜欢
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    相关资源
    最近更新 更多