バージョンベースの一貫性の使用

バージョンベースの一貫性は、各操作ベースで使用されます。レプリカで行われる読取りが、少なくとも、マスターで以前に行われた書込み程度に最新であることが保証されます。

これが使用される場合の1つの例は、顧客からの情報(名前など)を収集するWebアプリケーションです。そして、その名前の顧客に対して表示されるすべての後続ページをカスタマイズします。顧客の名前の格納は、マスター・ノードによってのみ実行できる書込み操作ですが、後続ページの作成は、ストア内のいずれのノードでも起こる読取り専用操作として実行されます。

この一貫性ポリシーを使用するには、アプリケーション内のプロセス間でバージョン情報が転送される必要があります。

バージョンベースの一貫性ポリシーを作成するには、VersionConsistencyクラスを使用します。これを行う場合、次の情報を指定する必要があります。

  • ONDB_VERSION

    読取りで一致する必要のあるVersion。返される値は、ポリシーで指定されたバージョン以上です。

  • ONDB_TIMEOUT

    version要件を満たすためにレプリカが待機できる時間(ミリ秒)。つまり、レプリカがversion要件をすぐには満たさない場合、マスターからの必要なデータで更新されるかどうかをこの時間の間待ちます。レプリカがtimeout期間内に要件を満たさない場合、ConsistencyExceptionがスローされます。

たとえば、次のコードでは、ストア書込みを行い、バージョン情報を収集して、バージョンベースの一貫性ポリシーの作成に使用します。


from nosqldb import Consistency

from nosqldb import DurabilityException
from nosqldb import Factory
from nosqldb import IllegalArgumentException
from nosqldb import ProxyConfig

from nosqldb import ReadOptions
#### constant needed for ReadOptions
from nosqldb import ONDB_CONSISTENCY
from nosqldb import ONDB_VERSION_CONSISTENCY
from nosqldb import ONDB_TIMEOUT

from nosqldb import RequestTimeoutException
from nosqldb import Row
from nosqldb import StoreConfig
from nosqldb import WriteOptions
##### Constants needed for the write options
from nosqldb import ONDB_RETURN_CHOICE

from nosqldb import VersionConsistency
### Constants needed for the VersionConsistency
from nosqldb import ONDB_TIMEOUT
from nosqldb import ONDB_VERSION

import logging
import os
import sys

# locations where our store and proxy can be found
kvlite = 'localhost:5000'
proxy = 'localhost:7010'

# set logging level to debug and log to stdout
def setup_logging():
    rootLogger = logging.getLogger()
    rootLogger.setLevel(logging.DEBUG)

    logger = logging.StreamHandler(sys.stdout)
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter('\t%(levelname)s - %(message)s')
    logger.setFormatter(formatter)
    rootLogger.addHandler(logger)

# configure and open the store
def open_store():
    kvstoreconfig = StoreConfig('kvstore', [kvlite])
    return Factory.open(proxy, kvstoreconfig)

def write_row(store):
    row_d = { 'item' : 'bolts',
               'description' : "Hex head, stainless",
               'count' : 5,
               'percentage' : 0.2173913}
    row = Row(row_d)

    ## Create the write options
    wo = WriteOptions({ONDB_RETURN_CHOICE : 'VERSION'})
    try:
        matchVersion = store.put("myTable", row, wo)
        ## matchVersion is actually a tuple, the second element of 
        ## which identifies the table that the row was written to.
        return matchVersion[0]
    except IllegalArgumentException, iae:
        logging.error("Could not write table.")
        logging.error(iae.message)
    except DurabilityException, de:
        logging.error("Could not write table. Durability failure.")
        logging.error(de.message)
    except RequestTimeoutException, rte:
        logging.error("Could not write table. Exceeded timeout.")
        logging.error(rte.message) 

このアプリケーション・コードの別の箇所、あるいはまったく別のアプリケーションで、上で取得したmatchVersionを使用してバージョンベースの一貫性ポリシーを作成します。

def display_row(row):
    try:
            print "Retrieved row:"
            print "\tItem: %s" % row['item']
            print "\tDescription: %s" % row['description']
            print "\tCount: %s" % row['count']
            print "\tPercentage: %s" % row['percentage']
            print "\n"
    except KeyError, ke:
        logging.error("Row display failed. Bad key: %s" % ke.message)

def read_row(store, matchVersion):
    vc = VersionConsistency({ONDB_VERSION : matchVersion,
                            ONDB_TIMEOUT : 1000})

    consistency = Consistency({ONDB_VERSION_CONSISTENCY: vc})


    ro = ReadOptions({ONDB_CONSISTENCY : consistency,
                      ONDB_TIMEOUT : 1000})

    try:
        primary_key_d = {"item" : "bolts"}
        row = store.get("myTable", primary_key_d, ro)
        if not row:
            logging.debug("Row retrieval failed")
        else:
            logging.debug("Row retrieval succeeded.")
            display_row(row)
    except IllegalArgumentException, iae:
        logging.error("Row retrieval failed.")
        logging.error(iae.message)
        return
    except ConsistencyException, ce:
        logging.error("Row retrieval failed due to Consistency.")
        logging.error(ce.message)
    except RequestTimeoutException, rte:
        logging.error("Row retrieval failed, exceeded timeout value.")
        logging.error(rte.message)


if __name__ == '__main__':

    setup_logging()
    store = open_store()
    matchVersion = write_row(store)
    read_row(store, matchVersion)
    store.close()