imzhenyu / rDSN

Robust Distributed System Nucleus (rDSN) is an open framework for quickly building and managing high performance and robust distributed systems.
MIT License
33 stars 11 forks source link

parallel execution of read and write may cause inconsistency #457

Open qinzuoyan opened 8 years ago

qinzuoyan commented 8 years ago

As in the following code:

MODULE_INIT_BEGIN(replication_type1)
    dsn_task_code_register("RPC_L2_CLIENT_READ", TASK_TYPE_RPC_REQUEST, TASK_PRIORITY_COMMON, THREAD_POOL_LOCAL_APP);
    dsn_task_code_register("RPC_L2_CLIENT_WRITE", TASK_TYPE_RPC_REQUEST, TASK_PRIORITY_LOW, THREAD_POOL_REPLICATION);
    dsn::register_layer2_framework< ::dsn::replication::replication_service_app>("replica", DSN_APP_MASK_FRAMEWORK);
MODULE_INIT_END

on_client_read() is executed in LOCAL_APP thread pool, which is not partitioned. on_client_write() is executed in REPLICATION thread pool, which is partitioned. So it is:

In replica::on_client_read(), we need to read these variables:

Then there are risks of breaking strong consistency semantics of read operation. For example:

imzhenyu commented 8 years ago

This is as expected. One way to fix this is to use big locks, and another easy way is to reconfigure the read tasks to be executed in replication thread pool as well. It really depends on the semantic requirements though. In practice, since the reads and the writes requests are usually from different nodes, there is no point about reading the latest update or the stale update, as they are really depending on the msg scheduling on the network. If we do have such requirement, we will use some application-level approaches to guarantee that, i.e., read begins after getting the ack for the writes.