Elasticsearch系列---实现分布式锁 (3)

结果肯定会报错:

{ "error": { "root_cause": [ { "type": "version_conflict_engine_exception", "reason": "[lock][1]: version conflict, document already exists (current version [8])", "index_uuid": "XD7LFToWSKe_6f1EvLNoFw", "shard": "3", "index": "files-lock" } ], "type": "version_conflict_engine_exception", "reason": "[lock][1]: version conflict, document already exists (current version [8])", "index_uuid": "XD7LFToWSKe_6f1EvLNoFw", "shard": "3", "index": "files-lock" }, "status": 409 }

线程读数据完成后,对共享锁进行释放,执行释放锁的脚本

POST /files-lock/lock/1/_update { "script": { "id": "rw-unlock" } }

释放1次lock_count减1,减到0时,说明所有的共享锁已经释放完毕,就把这个doc删除掉

所有共享锁释放完毕,尝试加排他锁

PUT /files-lock/lock/1/_create { "lock_type": "exclusive" }

此时能够加锁成功,响应报文:

{ "_index": "files-lock", "_type": "lock", "_id": "1", "_version": 1, "found": true, "_source": { "lock_type": "exclusive" } }

有排他锁的情况,尝试加一个共享锁,失败信息如下:

{ "error": { "root_cause": [ { "type": "remote_transport_exception", "reason": "[node-1][192.168.17.137:9300][indices:data/write/update[s]]" } ], "type": "illegal_argument_exception", "reason": "failed to execute script", "caused_by": { "type": "script_exception", "reason": "runtime error", "painless_class": "java.lang.String", "to_string": "one thread is writing data, the lock is exclusive now", "java_class": "java.lang.String", "script_stack": [ "Debug.explain('one thread is writing data, the lock is exclusive now'); } ", " ^---- HERE" ], "script": "rw-lock", "lang": "painless", "caused_by": { "type": "painless_explain_error", "reason": null } } }, "status": 400 }

排他锁事务执行完成时,删除文档即可对锁进行释放

DELETE /files-lock/lock/1

脚本解释

读锁的加锁脚本和释放锁脚本,成对出现,用来统计线程的数量。

写锁利用_create语法来实现,如果有线程对某一文档有读取操作,那么对这个文档执行_create操作肯定报错。

小结

利用Elasticsearch一些语法的特性,加上painless脚本的配合,也能完整的复现全局锁、行锁、读写锁的特性,实现的思路还是挺有意思的,跟使用redis、zookeeper实现分布式锁有异曲同工之处,只是生产案例上用redis实现分布式锁是比较成功的实践,Elasticsearch的对这种分布式锁的实现方式可能不是最佳实践,但也可以了解一下。

专注Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区
可以扫左边二维码添加好友,邀请你加入Java架构社区微信群共同探讨技术

Java架构社区

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdpdw.html