Elasticsearch基于Painless脚本实现读写锁

Elasticsearch默认的并发控制

在Elasticsearch中默认是使用乐观锁基于_version字段来实现并发控制的,_version字段记录的时候每次更新的版本号,只有拿到最新版本号的client才能更新成功,其他拿到过期数据的client则更新失败。

Elasticsearch悲观锁控制方案

下面介绍一下基于Painless脚本实现的Elasticsearch悲观锁方案。
读锁(s锁):允许多个线程同时持有,用于对共享资源的读取,与写锁互斥。
写锁(x锁):具有排他性,同一时间只能允许一个线程持有,用于对共享资源的写操作。

对document加写锁

在这里专门建立了一个index用于锁的管理,下面展示的是对docment id为1的文档加写锁,如果这时锁是不存在的,直接创建document,并且字段
lock_type=x代表是写锁标志。如果这时锁已经存在,则直接返回noop,无修改就作为上锁失败的标志,使用返回结果里的result=noop作为判断。

POST /my_lock/_update/1
{
  "upsert":{
    "lock_type": "x",
    "read_lock_count":0
  },
  "script": {
    "lang": "painless",
    "source": """
      ctx.op = 'noop';
      return 
      """
    }
}
对document加读锁

如果锁不存在同样新建document,并且设lock_type=s作为读锁的标志。如果锁存在,则判断锁类型,如果是写锁的话,直接返回noop表示上锁失败。如果是读锁的话则将read_lock_count字段加1,表示此时持有读锁的线程数量。

POST /my_lock/_update/1
{
  "upsert":{
    "lock_type": "s",
    "read_lock_count":1
  },
  "script": {
    "lang": "painless",
    "source": """
      if(ctx._source.lock_type == params.lock_type){
        ctx._source.read_lock_count += 1;
        return
      }
      ctx.op = 'noop';
      return 
      """,
    "params": {
      "lock_type": "s"
      }
    }
}
锁的释放

判断锁的类型,如果是读锁并且持有读锁的数量大于1的话就将持有读锁的数量减一,否则直接将这个锁delete掉。

POST /my_lock/_update/1
{
  "script": {
    "lang": "painless",
    "source": """
      if(ctx._source.lock_type == "s" && ctx._source.read_lock_count>1){
        ctx._source.read_lock_count -= 1;
        return
      }
      ctx.op = 'delete';
      return 
      """
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值