我正在使用NodeJS,Kafka和Elasticsearch堆栈开展项目。我们有一个帐户微服务,需要确保帐户余额和交易的数据一致性(对某些客户来说,余额只能是负值)。
认为我们不需要实时交易结果,每个操作都可以异步处理,之后结果会显示给客户,有一些模型(如事件源,CQRS)提供数据没有ACID数据库的交易的一致性?
如果该模型只是做ACID数据库已经做的事情(并且做得很好),我们将实现一个SQL数据库(PostgreSQL)以适应这种情况。
答案 0 :(得分:1)
这不是Elasticsearch的创建方式。虽然您可以在某种程度上使用事务和锁定,但它将保持“最终一致”数据库
您可以查看以下链接,了解elasticsearch中可用的内容:
https://www.elastic.co/blog/versioning
https://www.elastic.co/guide/en/elasticsearch/guide/current/concurrency-solutions.html
https://www.elastic.co/blog/found-elasticsearch-as-nosql
https://discuss.elastic.co/t/transactional-acid-features-in-es/5357/2
versioning的使用案例:
假设我们需要更新来自不同工作人员的资源。常见的方法是:
在竞争条件下,只有第一个服务才会执行请求而不会出错。其他竞争对手必须尝试,直到他们成功。 Elasticsearch保证了这种交易的一致性。
示例:
# creating the resource, take a look on _version field
# POST test/resources/42
{
"_index": "test",
"_type": "resources",
"_id": "42",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"created": true
}
# reading the resource
# GET test/resources/1
{
"_index": "test",
"_type": "resources",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"value": 1
}
}
# service number 1 trying to update the resource using version in url
# POST test/resources/1?version=1
# {...}
# response has new version
{
"_index": "test",
"_type": "resources",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"created": false
}
# service number 1 trying to update the resource -- fails
# POST test/resources/1?version=1
# {...}
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[resources][1]: version conflict, current version [2] is different than the one provided [1]",
"index_uuid": "nQcwn90wQ9WauH9ySC7qEw",
"shard": "3",
"index": "test"
}
],
"type": "version_conflict_engine_exception",
"reason": "[resources][1]: version conflict, current version [2] is different than the one provided [1]",
"index_uuid": "nQcwn90wQ9WauH9ySC7qEw",
"shard": "3",
"index": "test"
},
"status": 409
}
答案 1 :(得分:0)
是的,您可以执行transactional processing in Apache Kafka(vid),并且您还可以使用kafka-connect-elasticseach连接器(more info)将数据幂等地置于Elastic。
答案 2 :(得分:0)
如果需要此功能,则可以遵循两阶段提交协议来模拟Elasticsearch中的事务,该协议涉及创建事务日志。这样可以确保所有事务完成或允许它们回滚。完整的说明可以在以下网址查看:https://alexmarquardt.com/2019/12/05/emulating-transactional-functionality-in-elasticsearch-with-two-phase-commits/