<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 概述 MySQL 原有線程調度方式有每個連接一個線程(one-thread-per-connection)和所有連接一個線程(no-threads)。 no-threads一般用于調試,生產環境一般用one-thread-per-connection方式。one-thread-per-connection 適合于低并發長連接的環境,而在高并發或大量短連接環境下,大量創建和銷毀線程,以及線程上下文切換,會嚴重影響性能。另外 one-thread-per-connection 對于大量連接數擴展也會影響性能。 為了解決上述問題,MariaDB、Percona、Oracle MySQL 都推出了線程池方案,它們的實現方式大體相似,這里以 Percona 為例來簡略介紹實現原理,同時會介紹我們在其基礎上的一些改進。 ## 實現 線程池方案下,用戶的每個連接不再對應一個線程。線程池由一系列 worker 線程組成,這些worker線程被分為`thread_pool_size`個group。用戶的連接按 round-robin 的方式映射到相應的group 中,一個連接可以由一個group中的一個或多個worker線程來處理。 1. listener 線程 每個group中有一個listener線程,通過epoll的方式來監聽本group中連接的事件。listener線程同時也是worker線程,listener線程不是固定的。 listener線程監聽到連接事件后會將事件放入優先級隊列中,listener線程作為worker線程也處理一些連接事件,以減少上下文切換。 listener線程會檢查優先級隊列是否為空,如果為空表示網絡空閑,listener線程會作為worker線程處理第一個監聽事件,其他事件仍然放入優先級隊列中。 另外,當沒有活躍線時,listener會喚醒一個線程,如果沒有線程可以喚醒,且當前group只有一個線程且為listener,則創建一個線程。 2. 優先級隊列 分為高優先級隊列和普通隊列,已經開啟的事務并且tickets不為0,放入高優先隊列,否則放入普通隊列。每個連接在`thread_pool_high_prio_tickets`次被放到優先隊列中后,會移到普通隊列中。worker線程先從高優先隊列取event處理,只有當高優先隊列為空時才從普通隊列取event處理。 通過優先級隊列,可以讓已經開啟的事務或短事務得到優先處理,及時提交釋放鎖等資源。 3. worker 線程 worker線程負責從優先隊列取事件處理。如果沒有取到event,會嘗試從epoll中取一個,如果沒有取到再進入等待,如果等待超過`thread_pool_idle_timeout`?worker線程會退出。 4. timer 線程 每隔`thread_pool_stall_limit`時間檢查一次。 * listener沒有接收新的事件,listener正在等待時需調用`wake_or_create_thread`,重新創建listener; * 從上一次檢查起,worker線程沒有收到新的事件,并且隊列不為空,則認為發生了stall,需喚醒或創建worker線程; * 檢查`net_wait_timeout`是否超時,如果超時退出連接,而不是退出worker線程。 5. 何時喚醒或創建worker線程 * 從隊列中取事件時發現沒有活躍線程時; * worker線程發生等待且沒有活躍線程時; * timer線程認為發生了stall; ## 重要參數解析 1. `thread_pool_oversubscribe` 一個group中活躍線程和等待中的線程超過`thread_pool_oversubscribe`時,不會創建新的線程。 此參數可以控制系統的并發數,同時可以防止調度上的死鎖,考慮如下情況,A、B、C三個事務,A、B 需等待C提交。A、B先得到調度,同時活躍線程數達到了`thread_pool_max_threads`上限,隨后C繼續執行提交,此時已經沒有線程來處理C提交,從而導致A、B一直等待。`thread_pool_oversubscribe`控制group中活躍線程和等待中的線程總數,從而防止了上述情況。 2. `thread_pool_stall_limit` timer線程檢測間隔。此參數設置過小,會導致創建過多的線程,從而產生較多的線程上下文切換,但可以及時處理鎖等待的場景,避免死鎖。參數設置過大,對長語句有益,但會阻塞短語句的執行。參數設置需視具體情況而定,例如99%的語句10ms內可以完成,那么我們可以將就`thread_pool_stall_limit`設置為10ms ## 一些改進 1. lock tables read 的處理 對于聲明 lock tables read 等明確聲明表鎖的事件,放入高優先級隊列。 2. binlog dump線程的處理 binlog dump線程是典型的長事務場景,當多個binlog dump線程分配到同一個group中時,group中的線程很容易超過`thread_pool_oversubscribe`限制,從而導致性能下降。 優化方法是修改binlog dump線程不受`thread_pool_oversubscribe`限制。 3. 豐富診斷信息`information_schema.thread_group_status` ~~~ show create table THREAD_GROUP_STATUS\G *************************** 1. row *************************** Table: THREAD_GROUP_STATUS Create Table: CREATE TEMPORARY TABLE `THREAD_GROUP_STATUS` ( `ID` int(21) unsigned NOT NULL DEFAULT '0', `THREAD_COUNT` int(21) unsigned NOT NULL DEFAULT '0', `ACTIVE_THREAD_COUNT` int(21) unsigned NOT NULL DEFAULT '0', `CONNECTION_COUNT` int(21) unsigned NOT NULL DEFAULT '0', `WAITING_THREAD_COUNT` int(21) unsigned NOT NULL DEFAULT '0', `DUMP_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0', `LOW_QUEUE_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0', `HIGH_QUEUE_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0' ) ENGINE=MEMORY DEFAULT CHARSET=utf8 ~~~ 4. 線程池調度異常,無法連接的處理 對于本地登錄的用戶,走老的`one_thread_per_connection`邏輯,從而解決無法連接的情況。 ## 連接池和線程池的區別 最后說一點連接池和線程池的區別。連接池和線程池是兩個獨立的概念,連接池是在客戶端的優化,緩存客戶的連接,避免重復創建和銷毀連接。而線程池是服務器端的優化。兩者的優化角度不同,不相關,因此兩種優化可以同時使用。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看