2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

為什么分庫分表后不建議跨分片查詢

 liang1234_ 2019-02-13

來源:阿飛的博客

寫在前面:如果對分庫分表還不是很熟悉的,可以參考筆者之前的文章《分庫分表技術演進&最佳實踐》。

在這篇文章中提到了一個場景,即電商的訂單。我們都知道訂單表有三大主要查詢:基于訂單ID查詢基于商戶編號查詢,基于用戶ID查詢。且那篇文章給出的方案是基于訂單ID、商戶編號、用戶ID都有一份分庫分表的數據。那么為什么要這么做?能否只基于某一列例如用戶ID分庫分表,答案肯定是不能。

筆者基于sharding-sphere(GitHub地址:https://github.com/apache/incubator-shardingsphere)進行了一個簡單的測試,測試環(huán)境如下:

  1. 128個分表:image_${0..127};

  2. 數據庫服務器:32C64G;

  3. 數據庫版本:MySQL-5.7.23;

  4. 操作系統(tǒng):CentOS 6.9 Final;

  5. 連接池:druid 1.1.6;

  6. mysql-connector-java:6.0.5;

  7. mybatis:3.4.5;

  8. mybatis-spring:1.3.1;

  9. springboot:1.5.9.RELEASE;

  10. sharding-sphere-3.1.0;

  11. JVM參數:-Xmx2g -Xms2g -Xmn1g -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX: AlwaysPreTouch;

  12. druid配置:默認參數;

表信息如下:

-- id是分片鍵。備注,DDL是偽SQL
CREATE TABLE `image_${0..127}` (
  `id` varchar(32NOT NULL,
  `image_no` varchar(50NOT NULL,
  `file_name` varchar(200NOT NULL COMMENT '影像文件名稱',
  `source` varchar(32DEFAULT NULL COMMENT '影像來源',
  `create_date` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '影像文件創(chuàng)建時間',
  PRIMARY KEY (`id`),
  KEY `idx_image_no` (`image_no`)
ENGINE=InnoDB DEFAULT CHARSET=utf8;

第1個測試場景如下:

  • 每個分表大概160w數據;

  • 累計1w次跨分片(imageNo)查詢 PK. 帶分片(id)查詢;

測試結果如下:

分片鍵PK.跨分片鍵

結論:由測試結果可知,跨分片查詢相比帶分片鍵查詢的性能衰減了很多。

第2個測試場景如下:

  • 每個分表大概160w數據;

  • 累計1w次分別測試跨1個分表,8個分表、16個分表、32個分表、64個分表、128個分表,結果如下:

跨分片鍵查詢壓力測試

結論:跨的分表數量越大,跨分表查詢的性能越差;


  • 為什么慢

我們要弄明白跨分片查詢?yōu)槭裁催@么慢之前,首先要掌握跨分片查詢原理。以sharding-sphere為例,其跨分片查詢的原理是:通過線程池并發(fā)請求到所有符合路由規(guī)則的目標分表,然后對所有結果進行歸并。需要說明的是,當路由結果只有1個,即不跨分片操作時sharding-sphere不會通過線程池異步執(zhí)行,而是直接同步執(zhí)行,這么做的原因是為了減少線程開銷,核心源碼在ShardingExecuteEngine.java中)。

既然是這個執(zhí)行原理,為什么跨分片查詢,隨著跨分片數量越多,性能會越來越差?我們再看一下第2個測試場景,當測試跨1個分表時,1w次查詢只需要5889ms,即平均1次查詢不到1ms。所以性能瓶頸不應該在SQL執(zhí)行階段,而應該在結果歸并階段。為了驗證這個猜想,筆者空跑sharding-sphere依賴的并發(fā)執(zhí)行組件google-guava的MoreExecutors。其結果如下:

Multi-Thread Executor Test

結論:由這個測試結果可知,當并發(fā)執(zhí)行越來越多,其結果歸并的代價越來越大。

附--空跑sharding-sphere依賴的并發(fā)執(zhí)行組件google-guava的MoreExecutors的部分源碼如下:

public class ConcurrentExecutorTest {
    private static final ListeningExecutorService executorService;
    public static final int CONCURRENT_COUNT = 64;
    public static final int batchSize = CONCURRENT_COUNT;
    public static final int EXECUTOR_SIZE = 8;
    static {
        executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(EXECUTOR_SIZE));
        MoreExecutors.addDelayedShutdownHook(executorService, 60, TimeUnit.SECONDS);
    }

    private static <I, O> List<O> execute(final Collection<I> inputs) {
        if (inputs.isEmpty()) {
            return Collections.emptyList();
        }
        // 并發(fā)執(zhí)行
        Collection<ListenableFuture<O>> allFutures = asyncExecute(inputs);
        // 結果歸并
        return getResults(allFutures);
    }

    private static <I, O> Collection<ListenableFuture<O>> asyncExecute(final Collection<I> inputs) {
        Collection<ListenableFuture<O>> result = new ArrayList<>(inputs.size());
        for (final I each : inputs) {
            // 異步執(zhí)行時直接返回結果
            result.add(executorService.submit(() -> (O) each));
        }
        return result;
    }

    private static <O> List<O> getResults(final Collection<ListenableFuture<O>> allFutures) {
        List<O> result = new LinkedList<>();
        for (ListenableFuture<O> each : allFutures) {
            result.add(each.get());
        }
        return result;
    }
}

總結

跨分片查詢的性能這么差,為什么sharding-sphere還要去做呢?筆者認為首先sharding-sphere是一個通用的分庫分表中間件,而不是在某些特定條件才能使用的中間件,所以應該要盡可能的兼容所有SQL。其次,即使跨分片查詢性能這么差,這個主要是在OLTP系統(tǒng)中使用時要小心,在一些OLAP或者后臺管理系統(tǒng)等一些低頻次操作的系統(tǒng)中,還是可以使用的。

比如,賬戶表已經根據賬戶ID分表,但是在運營操作的后臺管理系統(tǒng)中維護賬戶信息時,肯定有一些操作的SQL是不會帶有分片鍵賬戶ID的,比如查詢賬戶余額最多的88個土豪用戶。這個時候,我們可以通過sharding-sphere中間件直接執(zhí)行這條低頻次SQL。而不需要為了這些操作引入es或者其他組件來解決這種低頻次的問題(當然,隨著系統(tǒng)的演進,最后可能還是需要引入es等一些中間件來解決這些問題)。所以,分庫分表中間件的跨分片查詢在項目特定階段能夠大大減少開發(fā)成本,從而以最短的時間上線業(yè)務需求。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多