<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      HBase中MVCC的實現機制及應用情況

      MVCC(Multi-Version Concurrent Control),即多版本并發控制協議,廣泛使用于數據庫系統。本文將介紹HBase中對于MVCC的實現及應用情況。

      MVCC基本原理

      在介紹MVCC概念之前,我們先來想一下數據庫系統里的一個問題:假設有多個用戶同時讀寫數據庫里的一行記錄,那么怎么保證數據的一致性呢?一個基本的解決方法是對這一行記錄加上一把鎖,將不同用戶對同一行記錄的讀寫操作完全串行化執行,由于同一時刻只有一個用戶在操作,因此一致性不存在問題。但是,它存在明顯的性能問題:讀會阻塞寫,寫也會阻塞讀,整個數據庫系統的并發性能將大打折扣。

      MVCC(Multi-Version Concurrent Control),即多版本并發控制協議,它的目標是在保證數據一致性的前提下,提供一種高并發的訪問性能。在MVCC協議中,每個用戶在連接數據庫時看到的是一個具有一致性狀態的鏡像,每個事務在提交到數據庫之前對其他用戶均是不可見的。當事務需要更新數據時,不會直接覆蓋以前的數據,而是生成一個新的版本的數據,因此一條數據會有多個版本存儲,但是同一時刻只有最新的版本號是有效的。因此,讀的時候就可以保證總是以當前時刻的版本的數據可以被讀到,不論這條數據后來是否被修改或刪除。

      更多關于MVCC基本思想的介紹,參考Wikipedia

      一個MVCC實現類

      見org.apache.hadoop.hbase.regionserver.MultiVersionConsistencyControl,用于控制Memstore中讀寫的一致性,其中維護兩個long型的變量:

      1)memstoreRead:用于記錄當前全局可讀的readPoint,同時為了每個客戶端讀請求能夠記錄自己發起請求時刻的readPoint,還有一個ThreadLocal的perThreadReadPoint變量,以及相關的set和get方法;

      2)memstoreWrite:用于記錄當前全局最大的writePoint,根據它為下個事務生成新的writePoint。

      MultiVersionConsistencyControl中關鍵的實現方法如下:

      1)WriteEntry beginMemstoreInsert():開始一個更新操作,將memstoreWrite加1,創建writeQueue并插入到writeQueue,并返回WriteEntry對象;

      2)void completeMemstoreInsert(WriteEntry e):完成當前更新操作,將WriteEntry對象標記為可讀,具體分兩步:

      • boolean advanceMemstore(WriteEntry e):從頭開始遍歷writeQueue,移除所有已完成的WriteEntry對象,最后將memstoreRead更新為最新已完成的memstoreWrite;
      • void waitForRead(WriteEntry e):阻塞當前線程,直到memstoreRead等于當前WriteEntry的memstoreWrite,至此表明當前WriteEntry之前的所有更新事務都已經完成。

      MVCC使用場景

      見org.apache.hadoop.hbase.regionserver.HRegion.java,每個Region包含一個Memstore,維護一個MultiVersionConsistencyControl對象。

      寫操作

      見HRegion.java中的以下寫操作的方法:

      1)put

      2)checkAndPut

      3)delete

      4)checkAndDelete

      5)internalFlushcache

      6)mutateRow

      7)mutateRowsWithLocks

      8)batchMutate

      最終會調用到applyFamilyMapToMemstore方法使用MVCC進行寫操作:

        /**
         * Atomically apply the given map of family->edits to the memstore.
         * This handles the consistency control on its own, but the caller
         * should already have locked updatesLock.readLock(). This also does
         * <b>not</b> check the families for validity.
         *
         * @param familyMap Map of kvs per family
         * @param localizedWriteEntry The WriteEntry of the MVCC for this transaction.
         *        If null, then this method internally creates a mvcc transaction.
         * @return the additional memory usage of the memstore caused by the
         * new entries.
         */
        private long applyFamilyMapToMemstore(Map<byte[], List<KeyValue>> familyMap,
          MultiVersionConsistencyControl.WriteEntry localizedWriteEntry) {
          long size = 0;
          boolean freemvcc = false;
      
          try {
            if (localizedWriteEntry == null) {
              localizedWriteEntry = mvcc.beginMemstoreInsert();
              freemvcc = true;
            }
      
            for (Map.Entry<byte[], List<KeyValue>> e : familyMap.entrySet()) {
              byte[] family = e.getKey();
              List<KeyValue> edits = e.getValue();
      
              Store store = getStore(family);
              for (KeyValue kv: edits) {
                kv.setMemstoreTS(localizedWriteEntry.getWriteNumber());
                size += store.add(kv);
              }
            }
          } finally {
            if (freemvcc) {
              mvcc.completeMemstoreInsert(localizedWriteEntry);
            }
          }
      
           return size;
         }
      View Code

      讀操作

      HRegion.java中通過private ConcurrentHashMap<RegionScanner, Long> scannerReadPoints;維護各個查詢請求的readPoint。

      以get或scan請求為例,最終會通過getScanner方法需要構造RegionScannerImpl對象:

      org.apache.hadoop.hbase.regionserver.HRegion.RegionScannerImpl

      1)根據Scan對象構造時設置好readPoint,scan.getIsolationLevel()分為READ_UNCOMMITTED和READ_COMMITTED,只有當READ_COMMITTED時根據MultiVersionConsistencyControl.resetThreadReadPoint(mvcc);設置當前scanner線程的readPoint,并插入到scannerReadPoints維護起來。

      2)根據scan需要讀取的column family,創建StoreScanner(根據bloom filter、time range、ttl篩選需要的MemStoreScanner和StoreFileScanner),添加到scanners中,并最終根據scanners構造出一個KeyValueHeap

      下面看下RegionScannerImpl中的next方法是每次查詢時需要調用的函數:

      boolean org.apache.hadoop.hbase.regionserver.HRegion.RegionScannerImpl.next(List<KeyValue> outResults, int limit) throws IOException

      而上述方法會通過KeyValueHeap的next方法讀取下一條數據:先定位到當前KeyValueScanner(即之前構造KeyValueHeap時傳入的MemStoreScanner或StoreScanner),然后調用next方法。

      StoreFileScanner和MemStoreScanner均為KeyValueScanner,通過其中的next()接口方法,分別調用到StoreFileScanner.java的skipKVsNewerThanReadpoint方法、Memstore.java中MemStoreScanner對象的getNext方法。

      1)StoreFileScanner.java的skipKVsNewerThanReadpoint方法:

        protected boolean skipKVsNewerThanReadpoint() throws IOException {
          long readPoint = MultiVersionConsistencyControl.getThreadReadPoint();
      
          // We want to ignore all key-values that are newer than our current
          // readPoint
          while(enforceMVCC
              && cur != null
              && (cur.getMemstoreTS() > readPoint)) {
            hfs.next();
            cur = hfs.getKeyValue();
          }
      
          if (cur == null) {
            close();
            return false;
          }
      
          // For the optimisation in HBASE-4346, we set the KV's memstoreTS to
          // 0, if it is older than all the scanners' read points. It is possible
          // that a newer KV's memstoreTS was reset to 0. But, there is an
          // older KV which was not reset to 0 (because it was
          // not old enough during flush). Make sure that we set it correctly now,
          // so that the comparision order does not change.
          if (cur.getMemstoreTS() <= readPoint) {
            cur.setMemstoreTS(0);
          }
          return true;
        }
      View Code

      2)  Memstore.java中MemStoreScanner對象的getNext方法:

          protected KeyValue getNext(Iterator<KeyValue> it) {
            long readPoint = MultiVersionConsistencyControl.getThreadReadPoint();
          
            while (it.hasNext()) {
              KeyValue v = it.next();
              if (v.getMemstoreTS() <= readPoint) {
                return v;
              }
            }
      
            return null;
          }
      View Code

       

      posted on 2014-08-12 12:44  大圓那些事  閱讀(6832)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 国产欧美精品一区二区三区-老狼| 三人成全免费观看电视剧高清| 久久精品无码免费不卡| 国产免费AV片在线看| 亚洲欧美自偷自拍视频图片| 福利视频在线一区二区| 性XXXX视频播放免费直播| www免费视频com| 国产极品粉嫩学生一线天| 国产成人无码一区二区三区在线| 久久亚洲精品人成综合网| 一本色道久久88精品综合| 欧洲中文字幕一区二区| 盱眙县| 亚洲精品日韩在线丰满| 亚洲精品综合网在线8050影院| 亚洲成av人片无码不卡播放器| 亚洲自偷自偷在线成人网站传媒| 99在线视频免费观看| 国产福利酱国产一区二区| 日韩精品一区二区三区日韩 | 日本阿v片在线播放免费| 风韵丰满熟妇啪啪区老熟熟女| 成人无码区在线观看| 麻豆亚州无矿码专区视频| 果冻传媒色av国产在线播放| 国产精品一区二区三区自拍| 久久久久免费看成人影片| 中文字幕国产精品av| 午夜福利片一区二区三区| 国产精品免费看久久久| 久久精品国产亚洲av成人| 人妻丰满熟妇无码区免费| 日本精品成人一区二区三区视频| 国产初高中生视频在线观看| 色二av手机版在线| 少妇被日自拍黄色三级网络| 洱源县| 九九热在线精品视频首页| 亚洲一区二区精品动漫| 中文字幕亚洲人妻系列|