锁定文件以更新一段数据或所有文件内容

Lock file for update one section of data or all the file content

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

但我认为这个问题有点复杂,例如要更新文件 api 需要 读取 之前的文件/部分(我们提供api 通过 name 读取 fileapplication 对象)
获取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

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

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

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

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

初始版本 1.
进程 B 读取文件,看到版本 1.
进程 A 读取文件,看到版本 1,然后写入将版本增加到 2,然后更新文件。
所以现在写之前的进程B会比较版本。由于它的版本(版本 1)低于当前版本(版本 2),因此它必须 abort/retry 它的操作。

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

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

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

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

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

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

类似这样的伪代码:

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