Created
August 16, 2018 17:47
-
-
Save ingenthr/1ed8e8a76eddfdd02e6089ed83701bb6 to your computer and use it in GitHub Desktop.
TAP snapshot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE section PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN' | |
'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd' [ | |
<!ENTITY % every.entities SYSTEM "entities.ent"> | |
%every.entities; | |
]> | |
<section id="membase-tap-protocol"> | |
<title>TAP Protocol</title> | |
<para> | |
Overview | |
</para> | |
<para> | |
Tap provides a mechanism to observe from the outside data changes | |
going on within a memcached server. | |
</para> | |
<note> | |
<para> | |
In current releases of Membase Server, TAP is only implemented for | |
Membase bucket types, not for memcached buckets | |
</para> | |
</note> | |
<para> | |
Use Cases | |
</para> | |
<para> | |
Tap is a building block for lots of new types of things that would | |
like to react to changes within a memcached server without having to | |
actually modify memcached itself. | |
</para> | |
<para> | |
Replication | |
</para> | |
<para> | |
One simple use case is replication. Upon initial connect, a client | |
can ask for all existing data within a server as well as to be | |
notified as values change. We receive all data related to each item | |
that's being set, so just replaying that data on another node makes | |
replication an easy exercise. | |
</para> | |
<para> | |
Observation | |
</para> | |
<para> | |
Requesting a tap stream of only future changes makes it very easy to | |
see the types of things that are changing within your memcached | |
instance. | |
</para> | |
<para> | |
Secondary Layer Cache Invalidation | |
</para> | |
<para> | |
If you have frontends that are performing their own cache, | |
requesting a tap stream of future changes is useful for invalidating | |
items stored within this cache. | |
</para> | |
<para> | |
Ideally, such a stream would not include the actual data that had | |
changed. Today, all tap streams include full bodies, but specifying | |
new features that can be implemented by engines such as requesting | |
the omission of values is very straightforward. | |
</para> | |
<para> | |
External Indexing | |
</para> | |
<para> | |
A tap stream pointed at an index server (e.g. sphinx or solr) will | |
send all data changes to the index allowing for an always-up-to-date | |
full-text search index of your data. | |
</para> | |
<para> | |
vbucket transition | |
</para> | |
<para> | |
For the purposes of vbucket transfer between nodes, a new type of | |
tap request can be created that is every item stored in a vbucket | |
(or set of vbuckets) that is both existing and changing, but with | |
the ability to terminate the stream and cut-over ownership of the | |
vbucket once the last item is enqueued. | |
</para> | |
<para> | |
Protocol | |
</para> | |
<para> | |
A tap session begins by initiating a command from the client which | |
tells the server what we're interested in receiving and then the | |
server begins sending /client/ commands back across the connection | |
until the connection is terminated. | |
</para> | |
<para> | |
Moxi does not support proxy of the TAP sessions, so you have to | |
connect to the server you are interested in on port 11210. (Like all | |
other traffic, you must authenticate using | |
SASL to connect to the desired bucket) | |
</para> | |
<para> | |
Initial Base Message | |
</para> | |
<para> | |
A tap stream begins with a binary protocol message with the ID of | |
0x40 . The packet's key may specify a unique client identifier that | |
can be used to allow reconnects (resumable at the server's | |
discretion). A simple base message from a client referring to itself | |
as "node1" would appear as follows. | |
</para> | |
<programlisting>Byte/ 0 | 1 | 2 | 3 | | |
/ | | | | | |
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ | |
0| 80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ | |
4| 04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
8| 00 | 00 | 00 | 09 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
32| 31 ('1') | | |
</programlisting> | |
<programlisting>Header breakdown | |
tap connect command | |
Field (offset) (value) | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
Opcode (1) : 0x40 | |
Key length (2,3) : 0x0005 (5) | |
Extra length (4) : 0x04 | |
Data type (5) : 0x00 | |
vbucket (6,7) : 0x0000 (0) | |
Total body (8-11) : 0x00000009 (9) | |
Opaque (12-15): 0x00000000 | |
CAS (16-23): 0x0000000000000000 | |
Flags (24-27): 0x00000000 | |
Name (28-32): [node1] | |
</programlisting> | |
<para> | |
Options | |
</para> | |
<para> | |
Additional tap options may be specified as a 64-bit flags specifying | |
options. The flags will appear in the "extras" section of | |
the request packet. If omitted, it is assumed that all flags are 0. | |
</para> | |
<para> | |
Options may or may not have values. For options that do, the values | |
will appear in the body in the order they're defined (LSB -> | |
MSB). | |
</para> | |
<para> | |
Backfill | |
</para> | |
<para> | |
BACKFILL ( =0x01=) contains a single 64-bit body that represents the | |
oldest entry (from epoch) you're interested in. Specifying a time in | |
the future (for the server you are connecting to), will cause it to | |
start streaming only current changes. | |
</para> | |
<para> | |
An example tap stream request that specifies a backfill of -1 | |
(meaning future only) would look like this: | |
</para> | |
<programlisting>Byte/ 0 | 1 | 2 | 3 | | |
/ | | | | | |
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ | |
0| 80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ | |
4| 04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
8| 00 | 00 | 00 | 11 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 01 | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
32| 31 ('1') | ff | ff | ff | | |
+---------------+---------------+---------------+---------------+ | |
36| ff | ff | ff | ff | | |
+---------------+---------------+---------------+---------------+ | |
40| ff | | |
</programlisting> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x00000011 (17) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x00000001 backfill | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
Backfill date(33-40): 0xffffffffffffffff (-1) | |
</para> | |
<para> | |
Dump | |
</para> | |
<para> | |
DUMP ( =0x02=) contains no extra body and will cause the server to | |
transmit only existing items and disconnect after all of the items | |
have been transmitted. | |
</para> | |
<para> | |
An example tap stream request that specifies only dumping existing | |
records would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 09 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 02 | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
32| 31 ('1') | | |
</para> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x00000009 (9) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x00000002 dump | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
Specify vbuckets | |
</para> | |
<para> | |
LIST_VBUCKETS ( =0x04=) contains a list of vbuckets and will cause | |
the server to transmit only notifications about changes in the | |
specified vbuckets. | |
</para> | |
<para> | |
An example tap stream request that specifies 3 vbuckets (vbucket 0, | |
1 and 2) would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 11 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 04 | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
32| 31 ('1') | 00 | 03 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
36| 00 | 00 | 01 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
40| 02 | | |
</para> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x00000011 (17) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x00000004 list vbuckets | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
VBucket list (33-40): # listed (33-34): 0x0003 (3) vbucket (35-36): | |
0x0000 (0) vbucket (37-38): 0x0001 (1) vbucket (39-40): 0x0002 (2) | |
</para> | |
<para> | |
Transfer vbucket ownership | |
</para> | |
<para> | |
TAKEOVER_VBUCKETS ( =0x08=) contains no extra data and is used | |
together with LIST_VBUCKETS to transfer the ownership from the | |
server at the end of the dump of the server. | |
</para> | |
<para> | |
An example tap stream request that specifies 3 vbuckets (vbucket 0, | |
1 and 2) would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 11 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 0c | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
32| 31 ('1') | 00 | 03 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
36| 00 | 00 | 01 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
40| 02 | | |
</para> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x00000011 (17) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x0000000c list vbuckets, takeover vbuckets | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
VBucket list (33-40): # listed (33-34): 0x0003 (3) vbucket (35-36): | |
0x0000 (0) vbucket (37-38): 0x0001 (1) vbucket (39-40): 0x0002 (2) | |
</para> | |
<para> | |
ACK | |
</para> | |
<para> | |
SUPPORT_ACK ( =0x10=) contains no extra data and is to notify the | |
tap server that we (the consumer) support sending an ack message | |
back to the tap server whenever the tap server asks for an ack. | |
</para> | |
<para> | |
An example tap stream request that specifies that we support acks | |
would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 09 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 10 | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
32| 31 ('1') | | |
</para> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x00000009 (9) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x00000010 support ack | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
Keys only | |
</para> | |
<para> | |
KEYS_ONLY ( =0x20=) contains no extra data and is to notify the tap | |
server that we (the consumer) don't care about the values so we | |
would prefer that the tap server didn't send them. The server may | |
however decide to ignore your request. | |
</para> | |
<para> | |
An example tap stream request that specifies that we would prefer | |
the just the keys would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 09 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 20 | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
32| 31 ('1') | | |
</para> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x00000009 (9) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x00000020 request keys only | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
Complex example | |
</para> | |
<para> | |
You may of course mix all of the fields: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 40 ('@') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
04 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 1d | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 35 ('5') | | |
+---------------+---------------+---------------+---------------+ | |
28| 6e ('n') | 6f ('o') | 64 ('d') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
32| 31 ('1') | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
36| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
40| 05 | 00 | 05 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
44| 00 | 00 | 01 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
48| 02 | 00 | 03 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
52| 04 | | |
</para> | |
<para> | |
Header breakdown | |
</para> | |
<para> | |
tap connect command | |
</para> | |
<para> | |
Field (offset) (value) | |
</para> | |
<para> | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
</para> | |
<para> | |
Opcode (1) : 0x40 | |
</para> | |
<para> | |
Key length (2,3) : 0x0005 (5) | |
</para> | |
<para> | |
Extra length (4) : 0x04 | |
</para> | |
<para> | |
Data type (5) : 0x00 | |
</para> | |
<para> | |
vbucket (6,7) : 0x0000 (0) | |
</para> | |
<para> | |
Total body (8-11) : 0x0000001d (29) | |
</para> | |
<para> | |
Opaque (12-15): 0x00000000 | |
</para> | |
<para> | |
CAS (16-23): 0x0000000000000000 | |
</para> | |
<para> | |
Flags (24-27): 0x00000035 backfill, list vbuckets, support ack, | |
request keys only | |
</para> | |
<para> | |
Name (28-32): [node1] | |
</para> | |
<para> | |
Backfill date(33-40): 0x0000000000000005 (5) | |
</para> | |
<para> | |
VBucket list (41-52): # listed (41-42): 0x0005 (5) vbucket (43-44): | |
0x0000 (0) vbucket (45-46): 0x0001 (1) vbucket (47-48): 0x0002 (2) | |
vbucket (49-50): 0x0003 (3) vbucket (51-52): 0x0004 (4) | |
</para> | |
<para> | |
Response Commands | |
</para> | |
<para> | |
After initiating tap, a series of responses will begin streaming | |
commands back to the caller. These commands are similar to, but not | |
necessarily the same as existing commands. In particular, each | |
command includes a section of engine-specific data as well as a TTL | |
to avoid replication loops. [describe extended formats] | |
</para> | |
<para> | |
Mutation | |
</para> | |
<para> | |
All mutation events arrive as TAP_MUTATION ( =0x41=) events. These | |
are conceptualy similar to set commands. A mutation event for key | |
"mykey" with a value of "value" (no flags or | |
expiry) and a TTL of 255 would look like: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 41 ('A') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
10 | 00 | 00 | 66 ('f') | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 1a | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 03 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
28| ff | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
32| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
36| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
40| 6d ('m') | 79 ('y') | 6b ('k') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
44| 79 ('y') | 76 ('v') | 61 ('a') | 6c ('l') | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
48| 75 ('u') | 65 ('e') | | |
</para> | |
<para> | |
Header breakdown Field (offset) (value) Magic (0) : 0x80 | |
(PROTOCOL_BINARY_REQ) Opcode (1) : 0x41 (tap mutation) Key length | |
(2,3) : 0x0005 (5) Extra length (4) : 0x10 Data type (5) : 0x00 | |
vbucket (6,7) : 0x0066 (102) Total body (8-11) : 0x0000001a (26) | |
Opaque (12-15): 0x00000000 (0) CAS (16-23): 0x0000000000000003 (3) | |
Engine priv. (24-25): 0x0000 (0) Flags (26-27): 0x0000 TTL (28): ff | |
Reserved (29): 00 Reserved (30): 00 Reserved (31): 00 Item Flags | |
(32-35): 0x00000000 Item Expiry (36-39): 0x00000000 Key (40-44): | |
[mykey] Value (45-49): [value] | |
</para> | |
<para> | |
Delete | |
</para> | |
<para> | |
TAP_DELETE ( =0x42=) may contain an engine specific section. A | |
typical packet for deletion of "mykey" with a TTL of 255 | |
without any engine specific data would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 42 ('B') | 00 | 05 | | |
+---------------+---------------+---------------+---------------+ 4| | |
08 | 00 | 00 | 66 ('f') | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 0d | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
28| ff | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
32| 6d ('m') | 79 ('y') | 6b ('k') | 65 ('e') | | |
+---------------+---------------+---------------+---------------+ | |
</para> | |
<para> | |
36| 79 ('y') | | |
</para> | |
<para> | |
Header breakdown Field (offset) (value) Magic (0) : 0x80 | |
(PROTOCOL_BINARY_REQ) Opcode (1) : 0x42 (tap delete) Key length | |
(2,3) : 0x0005 (5) Extra length (4) : 0x08 Data type (5) : 0x00 | |
vbucket (6,7) : 0x0066 (102) Total body (8-11) : 0x0000000d (13) | |
Opaque (12-15): 0x00000000 (0) CAS (16-23): 0x0000000000000000 (0) | |
Engine priv. (24-25): 0x0000 (0) Flags (26-27): 0x0000 TTL (28): ff | |
Reserved (29): 00 Reserved (30): 00 Reserved (31): 00 Key (32-36): | |
[mykey] | |
</para> | |
<para> | |
Flush | |
</para> | |
<para> | |
TAP_FLUSH ( =0x43=) may contain an engine specific section. A | |
typical flush packet with a TTL of 255 without any engine specific | |
data would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 43 ('C') | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 4| | |
08 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 08 | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
28| ff | 00 | 00 | 00 | | |
</para> | |
<para> | |
Header breakdown Field (offset) (value) Magic (0) : 0x80 | |
(PROTOCOL_BINARY_REQ) Opcode (1) : 0x43 (tap flush) Key length (2,3) | |
: 0x0000 (0) Extra length (4) : 0x08 Data type (5) : 0x00 vbucket | |
(6,7) : 0x0000 (0) Total body (8-11) : 0x00000008 (8) Opaque | |
(12-15): 0x00000000 (0) CAS (16-23): 0x0000000000000000 (0) Engine | |
priv. (24-25): 0x0000 (0) Flags (26-27): 0x0000 TTL (28): ff | |
Reserved (29): 00 Reserved (30): 00 Reserved (31): 00 | |
</para> | |
<para> | |
Opaque | |
</para> | |
<para> | |
The purpose of the TAP_OPAQUE ( =0x44=) packet is for engine writers | |
to be able to send control data to the consumer. A tap opaque packet | |
with 4 bytes of engine specific data (0xff 0xff 0xff 0xff for | |
vbucket 1023 and a TTL of 255 would look like this: | |
</para> | |
<para> | |
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 | |
2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ 0| | |
80 | 44 ('D') | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ 4| | |
08 | 00 | 03 | ff | | |
+---------------+---------------+---------------+---------------+ 8| | |
00 | 00 | 00 | 0c | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 04 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
28| ff | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
32| ff | ff | ff | ff | | |
</para> | |
<para> | |
Header breakdown Field (offset) (value) Magic (0) : 0x80 | |
(PROTOCOL_BINARY_REQ) Opcode (1) : 0x44 (tap opaque) Key length | |
(2,3) : 0x0000 (0) Extra length (4) : 0x08 Data type (5) : 0x00 | |
vbucket (6,7) : 0x03ff (1023) Total body (8-11) : 0x0000000c (12) | |
Opaque (12-15): 0x00000000 (0) CAS (16-23): 0x0000000000000000 (0) | |
Engine priv. (24-25): 0x0004 (4) Flags (26-27): 0x0000 TTL (28): ff | |
Reserved (29): 00 Reserved (30): 00 Reserved (31): 00 | |
</para> | |
<para> | |
Set vbucket | |
</para> | |
<para> | |
The purpose of the TAP_VBUCKET ( =0x45=) packet is to set the state | |
of a virtual bucket in the consumer (this is part of vbucket | |
takeover) | |
</para> | |
<programlisting>Byte/ 0 | 1 | 2 | 3 | | |
/ | | | | | |
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| | |
+---------------+---------------+---------------+---------------+ | |
0| 80 | 45 ('E') | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
4| 08 | 00 | 00 | 38 ('8') | | |
+---------------+---------------+---------------+---------------+ | |
8| 00 | 00 | 00 | 0c | | |
+---------------+---------------+---------------+---------------+ | |
12| 00 | 00 | 00 | 39 ('9') | | |
+---------------+---------------+---------------+---------------+ | |
16| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
20| 00 | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
24| 00 | 04 | 00 | 01 | | |
+---------------+---------------+---------------+---------------+ | |
28| ff | 00 | 00 | 00 | | |
+---------------+---------------+---------------+---------------+ | |
32| 00 | 00 | 00 | 03 | | |
</programlisting> | |
<programlisting>Header breakdown | |
Field (offset) (value) | |
Magic (0) : 0x80 (PROTOCOL_BINARY_REQ) | |
Opcode (1) : 0x45 (tap vbucket set) | |
Key length (2,3) : 0x0000 (0) | |
Extra length (4) : 0x08 | |
Data type (5) : 0x00 | |
vbucket (6,7) : 0x0038 (56) | |
Total body (8-11) : 0x0000000c (12) | |
Opaque (12-15): 0x00000039 (57) | |
CAS (16-23): 0x0000000000000000 (0) | |
Engine priv. (24-25): 0x0000 (0) | |
Flags (26-27): 0x0001 | |
</programlisting> | |
<programlisting> ack | |
TTL (28): ff | |
Reserved (29): 00 | |
Reserved (30): 00 | |
Reserved (31): 00 | |
VB State (32-35): 0x00000003 (pending) | |
</programlisting> | |
<para> | |
Implementations and Samples | |
</para> | |
<para> | |
<command>vbucketmigrator</command> includes TAP client | |
implementations, and there is a sample Python client in the | |
membase engine source. There is also ongoing work on a specific | |
client for Java and Ruby. There is also a tutorial on accessing | |
TAP using the alpha libMembase. The behavior of TAP is defined in | |
the proposed memcached source. | |
</para> | |
</section> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment