ElasticSearch--锁

悲观锁
一上来就给数据加锁,其他人不能操作。
全局锁,直接锁住整个索引

全局锁

PUT /fs/lock/global/_create
fs:你要上锁的index
lokc:上锁的type
global:对应的doc的id。
_create:强制必须时创建,如果文档已经存在,那么会创建失败,报错。

执行:

PUT /fs/lock/global/_create
{}

如果其他线程执行会报错:

{
  "error": {
    "root_cause": [
      {
        "type": "version_conflict_engine_exception",
        "reason": "[lock][global]: version conflict, document already exists (current version [1])",
        "index_uuid": "6bNW_JLFSN6UiboCRfKQ4A",
        "shard": "2",
        "index": "fs"
      }
    ],
    "type": "version_conflict_engine_exception",
    "reason": "[lock][global]: version conflict, document already exists (current version [1])",
    "index_uuid": "6bNW_JLFSN6UiboCRfKQ4A",
    "shard": "2",
    "index": "fs"
  },
  "status": 409
}

删除上的锁:

DELETE /fs/lock/global

第一个上锁成功的线程能执行修改操作。
操作简单,成本低,但是并发不高。。。

文档锁
创建索引及type

PUT /fs

PUT /fs/_mapping/lock
{
  "lock":{
    "properties":{
      "process_id":{
        "type":"long"
      }
    }
  }
}

在es的config/scripts下创建judge-lock.groovy文件,

if ( ctx._source.process_id != process_id ) { assert false }; ctx.op = 'noop';

上文档锁

POST /fs/lock/1/_update
{
  "upsert": { "process_id": 123 },
  "script": {
    "lang": "groovy",
    "file": "judge-lock", 
    "params": {
      "process_id": 123
    }
  }
}

因为文档并不存在,会执行upsert中的语句,设置process_id的值为123,如果再次执行,因为process_id与文档中的值相同,则result值为noop。
如果传递不同的process_id,会报错。

POST /fs/lock/1/_update
{
  "upsert": { "process_id": 123 },
  "script": {
    "lang": "groovy",
    "file": "judge-lock", 
    "params": {
      "process_id": 222
    }
  }
}

刷新

POST /fs/_refresh 

查询该线程锁了那些文档,

GET /fs/lock/_search?scroll=1m
{
  "query": {
    "term": {
      "process_id": 123
    }
  }
}

然后批量删除

PUT /fs/lock/_bulk
{ "delete": { "_id": 1}}

然后其他的线程即可上锁了。

共享锁:这份数据是共享的,然后多个线程过来,都可以获取同一数据的共享锁,然后对这个数据执行读操作,
排他锁:只能有一个线程获取排他锁,然后执行增删改操作。
共享锁测试:

DELETE /fs

PUT /fs

PUT /fs/_mapping/lock
{
  "lock":{
    "properties":{
      "lock_type":{
        "type":"text"
      },
      "lock_count":{
        "type":"long"
      }
    }
  }
}

上共享锁:

POST /fs/lock/1/_update 
{
  "upsert": { 
    "lock_type":  "shared",
    "lock_count": 1
  },
  "script": {
  	"lang": "groovy",
  	"file": "judge-lock-2"
  }
}

judge-lock-2文件内容:

judge-lock-2.groovy: if (ctx._source.lock_type == 'exclusive') { assert false }; ctx._source.lock_count++

多个线程都可获取,

排它锁
当有线程获取了共享锁,如果获取排它锁,会执行异常

PUT /fs/lock/1/_create
{ "lock_type": "exclusive" }

解除锁即删除文档即可。

DELETE /fs/lock/1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值