<html dir="ltr"><head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<style id="owaTempEditStyle"></style><style title="owaParaStyle"><!--P {
        MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px
}
--></style>
<meta name="GENERATOR" content="MSHTML 8.00.7600.16625">
</head>
<body ocsi="x">
<div style="FONT-FAMILY: Tahoma; DIRECTION: ltr; COLOR: #000000; FONT-SIZE: x-small">
<div><font size="4">Hi openstackers,<br>
<br>
In order to implement </font><a href="https://blueprints.launchpad.net/magnetodb/+spec/support-tuneable-consistency" target="_blank"><font size="4">https://blueprints.launchpad.net/magnetodb/+spec/support-tuneable-consistency</font></a><font size="4"> we need
 tunable consistency support in MagnetoDB what is described here </font><a href="https://blueprints.launchpad.net/magnetodb/+spec/configurable-consistency" target="_blank"><font size="4">https://blueprints.launchpad.net/magnetodb/+spec/configurable-consistency</font></a><font size="4">
<br>
<br>
</font></div>
<div>
<div style="FONT-FAMILY: Tahoma; DIRECTION: ltr; COLOR: #000000; FONT-SIZE: x-small">
<div>
<div style="FONT-FAMILY: Tahoma; DIRECTION: ltr; COLOR: #000000; FONT-SIZE: x-small">
<div>
<div style="FONT-FAMILY: Tahoma; DIRECTION: ltr; COLOR: #000000; FONT-SIZE: x-small">
<div>
<div dir="ltr">
<div class="gmail_quote">
<div dir="ltr">
<div>
<div><font size="4">So, here is specification draft of concept.<br>
<br>
</font></div>
<font size="4">1. First of all, there is a list of suggested consistency levels for MagnetoDB:<br>
</font>
<ul>
<li><font size="4"><b>STRONG</b> - Provides the highest consistency and the lowest availability of any other level. (A write must be written to the commit log and memory table on all replica nodes in the cluster for that row. Read returns the record with the
 most recent timestamp after all replicas have responded.) </font></li><li><font size="4"><b>WEAK</b> - Provides low latency. Delivers the lowest consistency and highest availability compared to other levels. (A write must be written to the commit log and memory table of at least one replica node. Read returns a response from
 at least one replica node) </font></li><li><font size="4"><b>QUORUM</b> - Provides strong consistency if you can tolerate some level of failure. (A write must be written to the commit log and memory table on a quorum of replica nodes. Read returns the record with the most recent timestamp after
 a quorum of replicas has responded regardless of data center.)</font></li></ul>
</div>
<div><font size="4">    And special Multi Data Center consistency levels:</font></div>
<ul>
<li><font size="4"><b>MDC_EACH_QUORUM</b> - Used in multiple data center clusters to strictly maintain consistency at the same level in each data center. (A write must be written to the commit log and memory table on a quorum of replica nodes in
<i>all </i>data centers. Read returns the record with the most recent timestamp once a quorum of replicas in each data center of the cluster has responded.)<br>
</font></li><li><font size="4"><b>MDC_LOCAL_QUORUM </b>- Used in multiple data center clusters to maintain consistency in local (current) data center. (A write must be written to the commit log and memory table on a quorum of replica nodes in the same data center as the
 coordinator node. Read returns the record with the most recent timestamp once a quorum of replicas in the current data center as the coordinator node has reported. Avoids latency of inter-data center communication.)<br>
</font></li></ul>
<p><font size="4">BUT: We can't use inconsistent write if we use indexed table and condition operations which indexes based on. Because this staff requires the state of data. So it seems that we can:<br>
1) tune consistent read/write operation in the next combinations: QUORUM/QUORUM, MDC_LOCAL_QUORUM/MDC_EACH_QUORUM, MDC_EACH_QUORUM/MDC_LOCAL_QUORUM, STRONG/WEAK) .<br>
And also we have inconsistent read operation with CL=WEAK<br>
2) if we really need inconsistent write we can allow it for tables without indexing. In this case we provide more flexibility and optimization possibility, but on another hand we make MagnetoDB more complicated.</font></p>
<p><font face="tahoma"></font><br>
<font size="4"> </font></p>
<p><font size="4">2. JSON request examples.</font></p>
<p><font size="4" face="tahoma">I suggest adding new 'consistency_level' attribute. So we should check corresponding naming in backend API, cause it can be little different there.</font></p>
<p><font size="4" face="tahoma"></font> </p>
<p><font size="4">For read data operation we will use for example get item request:</font></p>
<p><font size="4">            {<br>
                "key": {<br>
                    "ForumName": {<br>
                        "S": "MagnetoDB"<br>
                    },<br>
                    "Subject": {<br>
                        "S": "What about configurable consistency support?"<br>
                    }<br>
                },<br>
                "attributes_to_get": ["LastPostDateTime","Message","Tags"],<br>
                "consistency_level": "STRONG"<br>
            }</font></p>
<p><font size="4">Here we use consistency level STRONG, so it means, that response returns the record with the most recent timestamp after all replicas have responded. In this case we will have the highest consistency but the lowest availability of any other
 level.</font></p>
<p><font size="4">For write data operation we will use for example put item request:</font></p>
<p><font size="4">            {<br>
                "item": {<br>
                    "LastPostDateTime": {<br>
                        "S": "201303190422"<br>
                    },<br>
                    "Tags": {<br>
                        "SS": ["Update","Multiple items","HelpMe"]<br>
                    },<br>
                    "ForumName": {<br>
                        "S": "Amazon DynamoDB"<br>
                    },<br>
                    "Message": {<br>
                        "S": "I want to update multiple items."<br>
                    },<br>
                    "Subject": {<br>
                        "S": "How do I update multiple items?"<br>
                    },<br>
                    "LastPostedBy": {<br>
                        "S": "</font><a href="mailto:fred@example.com"><font size="4">fred@example.com</font></a><font size="4">"<br>
                    }<br>
                },<br>
                "expected": {<br>
                    "ForumName": {<br>
                        "exists": false<br>
                    },<br>
                    "Subject": {<br>
                        "exists": false<br>
                    },<br>
                },<br>
                "consistency_level": "WEAK"<br>
            }<br>
        """</font></p>
<p><font size="4">Here we use consistency level WEAK, so it means, that write will be written to the commit log and memory table of at least one replica node. In this case we will have lowest consistency but highest availability compared to other levels.</font></p>
<p><font size="4" face="tahoma"></font> </p>
<p><font size="4" face="tahoma">And one more example for table creation:</font></p>
<p><font size="4" face="tahoma"></font> </p>
<p><font size="4" face="tahoma">            {<br>
                "attribute_definitions": [<br>
                    {<br>
                        "attribute_name": "ForumName",<br>
                        "attribute_type": "S"<br>
                    },<br>
                    {<br>
                        "attribute_name": "Subject",<br>
                        "attribute_type": "S"<br>
                    },<br>
                    {<br>
                        "attribute_name": "LastPostDateTime",<br>
                        "attribute_type": "S"<br>
                    }<br>
                ],<br>
                "table_name": "Thread",<br>
                "key_schema": [<br>
                    {<br>
                        "attribute_name": "ForumName",<br>
                        "key_type": "HASH"<br>
                    },<br>
                    {<br>
                        "attribute_name": "Subject",<br>
                        "key_type": "RANGE"<br>
                    }<br>
                ],<br>
                "consistency_level": "QUORUM"<br>
            }</font></p>
<p><font size="4" face="tahoma"></font> </p>
<p><font size="4" face="tahoma">Here we use consistency level QUORUM and set it to default consistency level to all write and read operations with this table. But we can post requests for it with another CL thereby change CL for needed operations.</font></p>
<p><font size="4" face="tahoma"></font> </p>
<p><font size="4">3. Default behaviour</font></p>
<p><font size="4">If we use in the "consistent read/write"request field value 'DEFAULT', or if we do not specify any level there or omit this field at all, we should use any default value for data consistency in MagnetoDB. I suggest
<b>QUORUM </b>level for it, because it provides quite strong consistency if we can tolerate some level of failure. So, we will have consistent data with QUORUM on read and write operations.</font></p>
<p><font size="4"></font> </p>
<p><font size="4">4. óhanges in database API.</font></p>
<p><font size="4">In this approach, changes in database api will be minimal. For example, let's see to the select_item method of storage API.</font></p>
<p><a href="https://github.com/stackforge/magnetodb/blob/master/magnetodb/storage/__init__.py#L162-L190" target="_blank"><font size="4">https://github.com/stackforge/magnetodb/blob/master/magnetodb/storage/__init__.py#L162-L190</font></a></p>
<p><font size="4">It takes 'consistent' argument and transmit it to lower level. Now it is boolean value. So we suggest to change it and use specific values, that we have suggested above, and transmit it to backend. There it will be mapped to backend-dependent
 consistency levels and be used by specific backend directly. For example, in Cassandra it will be used here:</font></p>
<p><a href="https://github.com/stackforge/magnetodb/blob/master/magnetodb/storage/impl/cassandra_impl.py#L265-L284" target="_blank"><font size="4">https://github.com/stackforge/magnetodb/blob/master/magnetodb/storage/impl/cassandra_impl.py#L265-L284</font></a></p>
<p><font size="4">To storage api methods, where we don't have such args, it will be added.</font></p>
<p><font size="4"></font> </p>
<p><font size="4">5. Error handling approach.</font></p>
<p><font size="4">We suggest to add validations. The first one should be done on the REST api level. If we have unsupported level in request (or maybe mistake etc.), we should return error. Another validation should be on the backend level: support it or not
<br>
such consistency level. Here we have 2 variants: 1) Return error and message about unsupported CL or 2) Use some default behaviour for specified backend. And the last validation will be directly in the backend DB, so if any, we will transmit it to higher level.<br>
</font></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>