[tarantool-patches] Re: [PATCH v2] replication: do not fetch records twice

  • From: Vladislav Shpilevoy <v.shpilevoy@xxxxxxxxxxxxx>
  • To: tarantool-patches@xxxxxxxxxxxxx, Konstantin Belyavskiy <k.belyavskiy@xxxxxxxxxxxxx>, georgy@xxxxxxxxxxxxx
  • Date: Tue, 10 Jul 2018 18:16:34 +0300

Hello. Thanks for the RFC! See my comments below.

+Building such topology is possible based on following principles:
+- Each node is required to notify all his downstream peers (replicas) in case 
of changes with his upstream subscription configuration. It could be done by 
add/update/delete records in **_routing** table.
+- The connection with lesser count of intermediate nodes has the highest 
priority. Lets define the number of edges between two peers as a Depth. So if A 
has direct connection with B, then Depth is 1 and if A connected with C through 
B, then Depth is 2. So if direct path between two nodes exists then it should 
be used in downstream peer subscription.
+- In case of equal Depth connections first wins. But if shorter path is found, 
then node first should reconnect and then notify downstream peers with updated 
paths.
+
+**_routing** table details.
+
+| Subscriber | Replication Source | Subscribed via | Depth   |
+| :--------- | :----------------- | :------------- | :------ |
+| UUID       | UUID               | UUID           | Integer |
+
+So peer notifies his downstream peers (replicas) with updates in **_cluster** table which replicates to peers.

Why _cluster? I thought that you use _routing table. And by the way, please, say
why we can not reuse _cluster for this? To be honest, I very upset at how much
new system spaces we are creating now: _routing here, _promotion in my patch.

Can't we find a way how to make them optional? How to create such system
replicaset spaces on demand?

When transmitting updated path to next level, increment Depth by one (if B 
connected to A with
depth X and B is has only one upstream C then record will be {UUID_C, UUID_A, 
UUID_B, X+1}).

Typo 'is has'.

And I can not understand. Please, explain in layman's terms. Here
C has replication source A and B, right?
And A has replication source B.
So C subscribed on B via A?

I would like to see here concrete box.cfg examples for each instance.

+
+### List of changes
+
+1. Extend IPROTO_SUBSCRIBE command with a list of server UUIDs for which 
SUBSCRIBE should fetch changes. Store this UUIDs within applier's internal data 
structure. By default issuing SUBSCRIBE with empty list what means no filtering 
at all.
+2. Implement white-list filtering in relay. After processing SUBSCRIBE 
request, relay has a list of UUIDs. Extract associated peer ids and fill in a 
filter. By default transmit all records, unless SUBSCRIBE was done with at 
least one server UUID. In latter case drop all records except originating from 
replicas in this list.
+3. After issuing REQUEST_VOTE to all peers, subscription logic knows a map of 
server UUIDs, their peers and their vclocks. For each reachable UUID select 
shortest path and assign UUIDs to direct peer through it this pass goes. Issue 
the subscribe requests. Notify downstream peers with new topology.
+4. Rebalancing. Connect/disconnect should trigger logic to start reassigning 
process.
+ - On disconnect first find "orphan" and then reassigned all reachable UUIDs 
to direct peers through who shortest path goes. Notify downstream peers.
+ - On connect, by iterating through appliers list, find UUIDs with shorter 
path found, reassign them to correct peers and issue SUBSCRIBE for recently 
connected applier and for the one from whom we get these UUIDs back.
+

Why is so different connect/disconnect events processing? As I understand, in 
both cases you should
recalculate optimal routes in the same way, from scratch.

+### Details and open questions
+
+On connect (new client or the old one reconnects) two options are available:
+1. SUBSCRIBE only to direct peer and wait for updates in **_cluster** to 
initiate further subscriptions.
+2. SUBSCRIBE without any UUIDs (that means subscribe to all).
+
+## Rationale and alternatives
+
+### Topology Discovering
+
+Instead of **_cluster** table updates,

Again: _cluster or _routing?

encoded _iproto_ messages could be used. In this case, on every change in peer 
upstream topology, it should send a Map of *{UUID: depth}* representing its 
current list of subscriptions to all downstream peers (excluding subset of 
subscriptions obtaining from this peer in master-master configuration).
+
+### On network configuration change
+
+On network configuration change what first, to notify peers or try to 
resubscribe?
+1. If the peer is a direct peer, then we have most recent information about 
this node based on connection status. If available subscribe and immediately 
notify downstream peers.
+2. On disconnect, it's more complex since in a connected subset if some node 
is disconnected, others can try to reconnect to this dead node through other 
nodes, but they do decisions based on old information resulting to massive 
resubscribe request (node A thinks that it has connection to C through B, but B 
thinks that it is connected through A). So I think, first need to notify 
replicas, that connection is dropped, and if other path is available try to 
resubscribe and then notify all downstream again. Or need to think about some 
kind of acknowledgement since it could be based on outdated information.
+3. On shorter path found, first resubscribe, then notify downstream peers.
+4. Balancing. It's possible to slightly extend topology with number of peers 
subscribed for balancing but does it really needed?


Other related posts: