分散型システム・ストレージ・レイヤの読み書きプロセス


0分散クラスタのデータ整合性
分散クラスタの記憶層は、一般にキャッシュ層とデータ硬化層から構成される.
ストレージ層を読み書きする際には,データの整合性を考慮する必要がある.データ整合性は、強い整合性(リアルタイム整合性)と弱い整合性(最終整合性)に分けられ、データ整合性の要求に応じて読み書きプロセスも変更されます.次に、個人的な経験と結びつけて、2つの場合の読み書きプロセスの手順を示します.
一般的な簡単な分散システムでは、キャッシュ層はredisクラスタを使用することができ、硬化層はmysqlまたはmongodbクラスタを使用することができる.個人的な経験に限定され、本明細書で指すキャッシュ層はredisクラスタ、硬化層はmysqlまたはmongodbクラスタを指す.
次のすべての関数は、次の条件に従います.
  • 1データのkey(key="foo.bar")には、ごみ値rubbish(rubbish="rubish-13987401234-zbert-rubish")があります.
  • 2 key関連ロックはlock(例えばlock=「lock.foo.bar」)
  • である
  • lockは楽観的ロックであり、そのタイムアウト時間はttl(例えばttl=10 s)
  • である.
    1強力な一貫性システムの読み書きプロセス
    強力なコンシステンシシステムでは、キャッシュとデータベースのデータがリアルタイムで一致する必要があります.これは、書き込み操作中に複数の書き込み要求間の競合を防止するとともに、読み取り要求とその競合を防止することを要求する.
  • 書き込みフロー
     func write(key, value) err {
        err = "okay"
    
        // 1     lock    rand,    lock;
        rand = time().now() * getpid() * random()
        t0 = t1 = time().now()
        ret = "null"
        while ret != "okay" {
            t1 = time().now()
            if (t1 - t0) >= ttl {
                ret = "fail"
                goto fail
            }
    
            timeout = t1 - t0
            ret = redis.set(lock rand PX timeout NX)
        }
    
        // 2             
        ret = redis.set(key, rubish)
        if ret != "okay" {
           err = "fail"
           goto end
        }
    
        // 3   db (mysql or mongodb)
        ret = db.update(key, value)
        if ret != "okay" {
           err = "fail"
           goto end
        }
    
        // 4     
        ret = redis.set(key, value)
        if ret != "okay" {
           redis.del(key)
        }
    
        end:
        // 5    
        ret = get("lock.foo.bar")
        if ret == rand {
            redis.del(lock)
        }
    
        return
     }
    
  • リードフロー
  • リード・プロセスは、タイムアウト時間ttlにも使用され、その値は、1 sなどの書き込みプロセスのttlとは異なる場合がある.
        func read_cache(key) (err, value) {
            err = "okay"
    
            err, value = redis.get(key)
            if err == "okay" {
                if value == rubbish {
                    err = "fail"
                }
    
                return
            }
    
            return
        }
    
        func read(key) (err, value) {
            // 1      value
            err, value = read_cache(key)
            if err == "okay" {
                return
            }
    
            // 2     lock    rand,    lock;
            rand = time().now() * getpid() * random()
            t0 = t1 = time().now()
            ret = "null"
            while ret != "okay" {
                t1 = time().now()
                if (t1 - t0) >= ttl {
                    ret = "fail"
                    goto fail
                }
    
                timeout = t1 - t0
                ret = redis.set(lock rand PX timeout NX)
            }
    
            // 3   lock ,        ,          value   cache 
            err, value = read_cache(key)
            if err == "okay" && value != rubbish {
                goto end
            }
    
            // 4  db  value
            err, value = db.get(key)
            if err == "fail" {
                goto end
            }
    
            // 5   redis
            // err = redis.setnx(key, value) //      write    2   4   ,                    
            // if err != "okay" {
            //  //              ,        ,                
            //  err, value = read_cache(key)
            //  return
            // }
            err = redis.set(key, value)
    
            end:
            // 6    
            ret = get("lock.foo.bar")
            if ret == rand {
                redis.del(lock)
            }
    
            return
        }
    

    2弱いコンシステンシシステムの読み書きプロセス
    弱いコンシステンシシステムでは、データベースのデータ更新に成功した後、キャッシュは一定時間後にデータベースの値と一致することができ、読み取り要求がkeyの古い値を読み込んだ場合にも操作に成功したと考えられます.
  • リードフローの弱い一貫性条件下でのリードフローは、強い一貫性条件下でのフローと一致する.
  • 書き込みフロー
     func write(key, value) err {
        err = "okay"
        // 1     lock    rand,    lock;
            rand = time().now() * getpid() * random()
            t0 = t1 = time().now()
            ret = "null"
            while ret != "okay" {
                t1 = time().now()
                if (t1 - t0) >= ttl {
                    err = "fail"
                    goto end
                }
    
                ret = redis.set(lock rand PX ttl NX)
            }
    
            // 2             
            ret, old_value = read(key)
            if ret != "okay" {
               err = "fail"
               goto end
            }
    
            // 3   db (mysql or mongodb)
            ret = db.update(key, value)
            if ret != "okay" {
               err = "fail"
               goto end
            }
    
            // 4     
            ret = redis.set(key, value)
            if ret != "okay" {
               redis.del(key)
            }
    
            end:
            // 5    
            ret = get("lock.foo.bar")
            if ret == rand {
                redis.del(lock)
            }
    
            return
     }