Jiazheng Shen
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    3
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 負載平衡和高度可用性 * NCNU OpenSource LSA 課程共筆 [Book mode](https://hackmd.io/@ncnu-opensource/book) * Load Balancing and High Availability @ 1092 LSA * 負載平衡和高度可用性 從網路層的 HA / LoadBalance、SLA、資源調配。 [TOC] ## 故事時間 ![](https://i.imgur.com/g2MwYQb.png) > 網友對於[上週二某 cdn 故障](https://www.ithome.com.tw/news/144911)所作的反應,轉載自 [Twitter](https://twitter.com/ninja_writer21/status/1402231025715933187) > (不過他們只花 [38 分鐘](https://status.fastly.com/incidents/vpk0ssybt3bj)就修好了) * 如果你架的服務很常壞掉,而且一壞掉要修很久才修好 * 使用者覺得你不可靠 * 不跟你買服務,不給你錢 * 你只好吃土 * 想辦法降低使用者不能用你服務的時間,就是本章要探討的問題 ## 什麼是可用性? * 一個系統處在可工作狀態的時間的比例 ### 計算方法 $Availability = \frac{E[\mathrm{uptime}]}{E[\mathrm{uptime}]+E[\mathrm{downtime}]} =\frac{MTBF}{MTBF + MTTR}$ :::info * Uptime 正常運行時間 * Downtime 當機時間;停機時間 * MTBF (Mean time between failures) 故障平均間隔時間,平均故障時間 * MTTR (Mean time to repair) 平均修復時間 ::: * 例子: * 我們的機器的平均每 81.5 年會發生故障 * MTBF = 81.5 x 365 x 24 = 713940 小時 * 每次故障平均要花 1 個小時來修好 * MTTR = 1 小時 * Avalability = 713940 / (713940+1) = 713940 / 713941 = 99.999860% * 4 個 9,5 個 9 ... 對應到能容許的停機時間, 來自[維基上的轉換表](https://en.wikipedia.org/wiki/High_availability#Percentage_calculation) | | 90% | 99% | 99.9% | 99.99% | 99.999% | | -------------- | -------- | - | - | - | - | | 每個月的停機時間 | 73.05 小時 | 7.31 小時 | 43.83 分鐘 | 4.38 分鐘 | 26.30 秒 | | 俗稱 | 1 個 9 | 2 個 9 | 3 個 9 | 4 個 9 | 5 個 9 | ### SLA * Service Level Agreement 服務層級協議 * 服務供應商與客戶之間訂定的協議或契約 * 服務層級目標(Service Level Objective,簡稱 SLO) * 可用性 * 客服在線上回應你問題的時段,例如 7x24x365 技術支援 * 違約時的賠償政策 * 給抵免額度 credit,該服務的餘額 * 排除之例外 * 排定停機時間 * 測試版功能 * 不可抗力因素 * 客戶違反使用協議 * 例子: * [臺灣 AI 雲端服務層級協議 (SLA) | zh - HackMD](https://man.twcc.ai/@twccdocs/terms-sla-zh) * [Amazon Compute Service Level Agreement](https://aws.amazon.com/compute/sla/) ## 高可用性 * 讓服務有很高機率的時間在線上,減少服務無法使用的時間 ### 誰需要 * 使用者數量較多的網路服務 * 例如:Google、LINE、YouTube、Cloudflare、AWS... * 企業的資料庫 * 例如 7-Eleven 平常都用收銀 POS 機來結帳,要是哪天不能用了,只能改用手寫來開收據,大大降低效率 * 股票交易系統,尤其在交易期間 * 延伸閱讀:[台灣證券交易所 - 不停頓與容錯的交易系統](http://sun.csim.scu.edu.tw/~epaper/newspaper/0028/includes/content_news9.php) * 重要基礎設施,水、電、航空交通管制... ### 需要考慮的環節 * 硬體:跳電、各種硬體(網路卡、硬碟)故障... * 有備用零件、雙電源、RAID (Redundant Array of Independent Disks) * 軟體:系統預期外的重啟、遇到 exception 不讓全部卡住 * 網路:線路的多元性 * 環境:火災、淹水、地震、停電、冷氣故障 * 把伺服器放在不同地理位置 * cold site / warm site / hot site [寫在之前備份主題共筆](https://hackmd.io/qh3eBiEtQj--Zp_piczxgQ?view#Backup-site--DR-site) * 人:操作失誤,ID10T error [梗](https://youtu.be/3klMcY8amOY) <!-- 例如 sudo rm -rf / --> ![](https://i.imgur.com/BZgs1zi.jpg) * 資料:沒有同步,不一致 ### 幾個大原則 * 監控錯誤的發生 (Monitoring) * 容錯移轉 (Failover) * 冗餘備援 (Redundancy) ### 監控錯誤的發生 Monitoring * 定期監控伺服器健康狀況,讓出問題時能趕快啟動救援機制 * 也叫做 Heartbeat / Health Checks * 自動偵測資源還能不能用 #### 不同層次的監控 * L3 網路層 * 發 ICMP 來看有沒有回覆 * L4 傳輸層 * 看 port 能不能 access * L7 應用層 * 看能不能存取到特定的 URL * 發送特定內容的請求,看回應內容是否符合預期結果 * 用自訂 shell / Python 腳本來測應用程式是否正常 #### 應用程式 health check 例子 * 所有 Linux 本機程式都通用 * `pgrep <PATTERN>` 來找 Process name 符合那個 pattern 的 Process ID * 如果找得到,會回傳 Process ID,exit status code 會回傳 0 * 如果 Process 不存在,exit status code 會回傳 1 * 例如:`pgrep nginx` ``` 1410 1411 ``` * 在 shell 看 exit status code 用 `echo $?` `0` * NGINX * Passive Health Checks * 在把 nginx 當作 reverse proxy 的情形下 * 當 nginx 存取 upstream server 失敗時,會自動把那台認為是 unhealthy,並一段時間內停止往它送請求 * 我們可以自訂一些參數 `sudo vim /etc/nginx/sites-available/default ` ```=nginx upstream stream_backend { server backend1.example.com:12345; server backend2.example.com:12345 max_fails=2 fail_timeout=30s; server backend3.example.com:12346; } ``` * `max_fails` 幾次失敗就認為不健康,預設為 1 * `fail_timeout` 在多久時間內失敗 max_fails 次,就認為不健康;和持續認為不健康多久,預設為 10 秒。(兩個共用同一參數) * 例如這裡讓 backend2 30 秒內試失敗 2 次的話,就停止往它送請求 30 秒 * MySQL * 用個低權限的使用者,來看是否能連線進資料庫 * 環境設定 * `sudo mysql` 進入 MySQL 命令列 * `mysql> CREATE DATABASE testdb;` 建立測試用資料庫 * 建立測試用表格 ``` mysql> CREATE TABLE example_table ( -> example_column varchar(30) -> ); ``` * `CREATE USER 'testuser' IDENTIFIED BY 'testuser';` 建立測試用使用者 * `GRANT SELECT ON testdb TO 'testuser';` 給予測試使用者權限 * 用 testuser 連進我們建的 testdb ```bash mysql -u testuser -ptestuser -e 'SELECT * FROM testdb.example_table' ``` * 若成功會回傳 exit status code 0,不成功則是 0 以外數值 * 在 shell 中執行 `echo $?`,會回傳上個指令的 exit status code * Docker (尚未經測試) * 在 Dockerfile 裡 ```=dockerfile FROM nginx RUN apt-get update && apt-get install -y curl HEALTHCHECK --interval=5s --timeout=3s \ CMD curl -fs http://localhost/ || exit 1 ``` * 增加 `HEALTHCHECK` 指示,讓 Docker 能執行 `CMD` 裡寫的指令,以確認 container 的健康狀況 * 執行 `CMD` 後回傳的 exit status code 若為 * 0: 代表成功,container 是健康的 * 1: 代表不健康 * 2: 內部保留值,別用 * `--interval`: 兩次健康檢查之間的時間間隔,預設為 30 秒。 * `--timeout`: 當健康檢查運行超過這時間,則本次檢查視為失敗。 * `--retries`: 當健康檢查連續失敗次數多於 retries 時,則視為 unhealthy。 * `docker build -t mynginx .` 來 build 成一個 image * `docker images` 查看是否有 build 成功 ``` REPOSITORY TAG IMAGE ID CREATED SIZE mynginx latest 991d5f1e0725 13 seconds ago 151MB ``` * `docker run mynginx` 把 image 執行起來 * 在 `docker ps` 能在 STATUS 那列看得到 `(healthy)` ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 94b77e6d91da mynginx "/docker-entrypoint.…" 24 seconds ago Up 22 seconds (healthy) 80/tcp vigilant_newton ``` * 用 `docker inspect mynginx` 可以查看 log 檔,也會記載 healthcheck 運行紀錄 > 參考資料:[Dockerfile reference | Docker Documentation](https://docs.docker.com/engine/reference/builder/#healthcheck) ### 容錯移轉 Failover * 自動從災難中復原(Disaster Recovery)的能力 * 災害復原計畫(Disaster Recovery Plan, DRP) * 回復時間目標(Recovery Time Objective, RTO) * 災難發生後,恢復需要花的的時間長短 * 資料回復點目標(Recovery Point Objective, RPO) * 前一次儲存的時間點 * 會受到資料備份頻率影響 * 如果不能即時複製,備份資料會落後生產環境一段時間,你能忍受有多少資料遺失 ![](https://i.imgur.com/RhaB2mw.png) > 圖片來源:[File:RPO RTO example converted.png - Wikimedia Commons](https://commons.wikimedia.org/wiki/File:RPO_RTO_example_converted.png), [CC BY 4.0](https://creativecommons.org/licenses/by/4.0) * Backup Site * cold site / warm site / hot site [寫在之前備份主題共筆](https://hackmd.io/qh3eBiEtQj--Zp_piczxgQ?view#Backup-site--DR-site) ### 冗餘 Redundancy * 有多台設備在運行同樣的任務 * 避免單點故障 (single point of failure) * 在多個環節避免單點故障 :::info **單點故障 (single point of failure)** 指系統中一旦失效,就會讓整個系統無法運作的部件。 換句話說,單點故障,全部故障。 ![](https://i.imgur.com/1hqhiJU.png) > [圖片設計原始檔](https://gist.github.com/jiazheng0609/2803c14351060061cf369ce33b2377bc),網路架構參考自:[Cisco Virtualized Multi-Tenant Data Center Framework - Cisco](https://www.cisco.com/c/en/us/td/docs/solutions/Enterprise/Data_Center/VMDC/2-2/vmdcframework.html) ::: * 藉由設立叢集(Cluster)來達成 ::: info **叢集(Cluster)** 一組鬆散或緊密連接在一起工作的電腦,且每個節點設定為執行相同的任務,由軟體控制和排程。 ![](https://i.imgur.com/ototzqd.png) > 圖片來源:[File:Beowulf.png - Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Beowulf.png) ::: #### 叢集的架構種類 * Active/Standby(Passive) Cluster ![](https://i.imgur.com/pqpaAae.png) * Hot standby * Active 那台在提供服務 * Standby 時時刻刻和 Active 保持一致,但不提供服務 * 等到 Active 掛掉的時候,Standby 能馬上跳出來做事 (Failover 機制) * Warm standby * Active 那台在提供服務 * Standby 定期複製 Active 的資料,且軟體還沒啟動 * 等到 Active 掛掉的時候,Standby 開始啟動服務 (Failover 機制) * Active/Active Cluster ![](https://i.imgur.com/XIjwTLD.png) > 以上兩張圖片來源:[Active-Active vs. Active-Passive High-Availability Clustering | JSCAPE](https://www.jscape.com/blog/active-active-vs-active-passive-high-availability-cluster) * 兩台 Active 同時有提供服務 * 靠 load balancer 來平均工作量 * Shared-Nothing vs. Shared-Disk Clusters * Shared-Disk Clusters ![](https://i.imgur.com/NmWXdXF.jpg) > 圖片來源:[File:Shared Disk Architecture.jpg - Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Shared_Disk_Architecture.jpg) * 多個前端 server 依靠單一資料庫 * 優點:節省成本 * 缺點:有單點故障危機 * Shared-Nothing ![](https://i.imgur.com/p7StjpO.jpg) > 圖片來源:[File:Shared Nothing Architecture.jpg - Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Shared_Nothing_Architecture.jpg) * 分成多個資料庫伺服器 * 優點:沒單點故障 * 缺點:資料要做 replication,很麻煩;要開多台機器,成本高 #### 資料複製 Replication * 叢集裡不同節點要同步資料,術語是複製 Replication ::: info **Replication 跟 Backup 有啥差別?** | | Replication 複製| Backup 備份| | -------- | -------- | -------- | | 執行時機 | 每次資料變更 | 固定間隔時間 | | 災難恢復時間 | 較短 | 較長 | ::: * 常見的複製方法 * 分散式檔案系統 * 一個經由網路同步的檔案系統 * 最主要設計目標是「通透性(Transparent)」,讓使用者感覺他只是一個本機的檔案系統 * 通透性:使用者完全不需要知道他是個分散式檔案系統,不需要去煩惱各種分散式系統可能帶來的問題,就能正常使用這服務 #### 資料庫叢集 * 這裡介紹最基礎 MySQL Replication 的作法 * source-replica 架構 | 主要角色 | 備用角色 | 註解 | | -------- | -------- | -------- | | Source | Replica | MySQL 8 後官方用詞 | | Master | Slave | 2020 年以前較多人用詞 | | Active | Standby | 參照本文「叢集的架構種類」段落 | ::: info **附註 為何有那麼多叫法?** 其實在 MySQL 8 之前,官方用詞是 master-slave,但自從「黑人的命也是命」(Black Lives Matter,BLM)運動受到重視後,許多帶有歧視眼光的技術字彙從 2020 年開始被慢慢改掉。 延伸閱讀:[iThome 新聞](https://www.ithome.com.tw/news/138616)、[官方說明](https://mysqlhighavailability.com/mysql-terminology-updates/)。 ::: * 原理 * binary log * source 會把所有資料變更動作寫進 binary log * replica 先去 source 把 binary log 逐行抓下來,存成 relay log * replica 再把 relay log 裡的資料變更動作套用在自己身上 * relay log * 記錄了檔案複製的進度,下一個 event 從什麼位置開始,由 mysql 負責更新 * binary log file position-based replication * 因為每次 replica 每次都是抓整個 binary log 下來 * 要讓 replica 知道從哪個 log 檔,從哪個位置開始要做重做,不然會一直做重複的事 * 一旦設定好,replica 會自己開始記複製到哪了 * 不同格式的 binary log * statement-based replication (SBR) * 把 SQL 指令記起來 * row-based replication (RBR) * 把表格裡每行變更記起來 * 例如 `sudo mysqlbinlog /var/log/mysql/mysql-bin.000002 -vv` 來看 binlog,`#` 開頭的都是工具幫我們做 base64 decode 的結果 ```=sql # at 373 #210606 8:01:12 server id 1 end_log_pos 427 CRC32 0x2e5e0aa4 Write_rows: table id 88 flags: STMT_END_F BINLOG ' yIC8YBMBAAAAPwAAAHUBAAAAAFgAAAAAAAEABGhhZGIADWV4YW1wbGVfdGFibGUAAQ8CeAABAgP8 /wCmxJQT yIC8YB4BAAAANgAAAKsBAAAAAFgAAAAAAAEAAgAB/wARZm91cnRoIGFmdGVyIEdUSUSkCl4u '/*!*/; ### INSERT INTO hadb.example_table ### SET ### @1='fourth after GTID' /* VARSTRING(120) meta=120 nullable=1 is_null=0 */ ``` * 光是只有冗餘的資料是不夠的!要成為一個高可用系統,尚未達成的要素: * Load balance - 透過 HAProxy VIP,實作於[期末專案](https://github.com/NCNU-OpenSource/hanetdb) * Monitor - 建個沒權限的使用者讓人戳,介紹於「[監控錯誤的發生](#監控錯誤的發生-Monitoring)」段落 * Failover - Group Replication * source 死掉時,其中一個 replica 要變更角色成為 source <!--* STONITH(Shoot The Other Node In The Head):當 source 死掉再復活時,他的資料已經落後生產環境了 (split-brain),不能直接上線,先擺進隔離區 (fencing) --> ::: info BlueT 補充:**CAP 定理(CAP theorem)** 在分散式系統中,不可能同時滿足下面三點: * 一致性 (Consistency):每次的讀取請求,都能取得最新資料。等同於所有節點都有同一份最新的資料 * 可用性 (Availability):每次請求資料時,都能得到非錯誤回應 * 分區容錯性 (Partition tolerance):就算網路出現問題導致有些資料遺失,整個系統仍然要可以繼續運作 這是個背後有許多討論空間的理論,在此僅略提起有此理論存在。 ::: ::: info BlueT 補充:**Raft Consensus Algorithm** 是一種共識演算法。在本章節所要介紹的 database replication 情境中,能解決「當 source 掛掉時怎麼選出新的 source」的這個問題。實際運作方式可參閱[此互動式網站](http://thesecretlivesofdata.com/raft/)。 ::: #### MySQL 叢集 DEMO * 以下用 Ubuntu 20.04 上的 MySQL 8.0.25 進行示範 * 檢查版本號碼 `mysql -V` * 若你的 MySQL 版本號碼小於 MySQL 8.0.22(或大約在 2020 年 7 月之前安裝) * 把所有大小寫 source 換成 master * 把所有大小寫 replica 換成 slave * 有兩台安裝完成的 MySQL Server * **source** 外界能對他**讀/寫** * **replica** 外界只能**讀** * 以下指令會因角色有所區分 1. 若 source 有防火牆,把他設為允許 replica 連入 * 在 **source** 上 `sudo ufw allow from replica-server-ip to any port 3306` 2. 在 **source** 上修改設定檔,預設有在裡面的可把 `#` 刪掉修改 * 在 **source** 上 `sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf` ```= bind-address = 192.168.57.7 server-id = 1 log_bin = /var/log/mysql/mysql-bin.log binlog_do_db = hadb ``` * 參數意思 * `bind-address` 填上你 source server 的 IP (可以用`ip a`看)。預設是 `127.0.0.1` 的話他只會接受來自本機的請求,所以要改才能讓 replica 進來 * `server-id` 只要和其他 replica 不重複就好 * `binlog_do_db` 填你想複製的 db 名字 * 如果需要複製更多 db,就多加幾行,像是 ```= binlog_do_db = db binlog_do_db = db_1 binlog_do_db = db_2 ``` * 接著重開 mysql `sudo systemctl restart mysql.service` 3. 建立要進來做複製的使用者,和給他權限 * 在 **source** 上,用 `sudo mysql` 或 `mysql -u <username> -p` 開啟 mysql 命令列 * mysql 命令列內 ```=sql mysql> CREATE USER 'replica'@'replica-server-ip' IDENTIFIED BY 'replica-password'; ``` * 參數意思 * `replica`、`replica-server-ip`、`replica-password` 等等設定 replica 會用到,他能從啥帳密從哪裡登進來 * 給予權限 ```=sql mysql> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'replica-server-ip'; mysql> FLUSH PRIVILEGES; ``` 4. 取得 source 的 binary log coordinates * 在 **source** 上,mysql 命令列內 * 將整個表格鎖定,讓其他連線無法讀取及異動,直到資料處理完畢為止 ```=mysql mysql> FLUSH TABLES WITH READ LOCK; ``` * 取得目前 binary log 檔案名稱和座標位置,等一下在 replica 會用到 ```=sql mysql> SHOW MASTER STATUS; -------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 73 | hadb | | +------------------+----------+--------------+------------------+ ``` 5. 這裡假設 source 資料庫裡還沒有 hadb,建立一個全新的 :::warning 若在執行本教學這些步驟之前 source 裡已經有資料,且想要複製到 replica 的,可參考 [之前的自動化共筆](https://hackmd.io/LqiMw8qRS2usU_IpQBe-Yg#%E8%87%AA%E5%8B%95%E5%8C%96%E4%BE%8B%E5%AD%90%E5%AF%A6%E4%BD%9C) 進行 mysqldump。 > 為啥就算 binlog 有從頭記還是建議 dbdump?因為 replica 包含所有歷史更動,太多。dbdump 只有最終結果。 ::: * 在 **source**,mysql 命令列內 * 剛剛鎖住了,先解鎖才能修改 ```=sql mysql> UNLOCK TABLES; Query OK, 0 rows affected (0.00 sec) ``` * 建立一個全新的 hadb ```=sql mysql> CREATE DATABASE hadb; Query OK, 1 row affected (0.01 sec) ``` 6. 開始設定 replica * 在 **replica** 上,修改設定檔 * `sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf` ```= bind-address = 192.168.57.8 server-id = 2 log_bin = /var/log/mysql/mysql-bin.log binlog_do_db = hadb relay-log = /var/log/mysql/mysql-relay-bin.log ``` * 參數意思 * `bind-address` 填上你 replica server 的 IP (可以用`ip a`看) * `server-id` 只要不跟 source 和其他 replica 重複就好 * `binlog_do_db` 填你想複製的 db 名字,跟 source 的一樣 * 接著重開 mysql `sudo systemctl restart mysql.service` 7. 開始複製 * 在 **replica**,進入 mysql 命令列 `sudo mysql` * 在 **replica**,mysql 命令列內 ```=sql mysql> CHANGE REPLICATION SOURCE TO mysql> SOURCE_HOST='source_server_ip', mysql> SOURCE_USER='replica', mysql> SOURCE_PASSWORD='replica-password', mysql> SOURCE_LOG_FILE='mysql-bin.000001', mysql> SOURCE_LOG_POS=73; ``` * 參數意思 * `SOURCE_USER` 和 `SOURCE_PASSWORD` 是要填在 2. 給權限的那組帳密 * `SOURCE_LOG_FILE` 和 `SOURCE_LOG_POS` 填在 3. 拿到的資訊 * 在 **replica**,mysql 命令列內 `mysql> START REPLICA;` 8. 測試複製是否有在運作 * 在 **source**,mysql 命令列內 * 切換到有在複製的 DB 裡 ```=sql mysql> USE hadb; ``` * 建立新 TABLE ```=sql mysql> CREATE TABLE example_table ( mysql> example_column varchar(30) mysql> ); Query OK, 0 rows affected (0.07 sec) ``` * 加入一些資料 ```=sql mysql> INSERT INTO example_table VALUES mysql> ('This is the first row'), mysql> ('This is the second row'), mysql> ('This is the third row'); Query OK, 3 rows affected (0.02 sec) Records: 3 Duplicates: 0 Warnings: 0 ``` * 在 **replica**,mysql 命令列內 * 切換到有在複製的 DB 裡 ```=sql mysql> USE hadb; ``` * 顯示資料 ```=sql mysql> SHOW TABLES; +----------------+ | Tables_in_hadb | +----------------+ | example_table | +----------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM example_table; +-------------------+ | example_column | +-------------------+ | this first row | | this second row | | this third row | +-------------------+ 3 rows in set (0.00 sec) ``` > 資料來源: [How To Set Up Replication in MySQL | DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-set-up-replication-in-mysql) ## 負載平衡 Load balancing * 把工作(load)分配下去給多台設備,讓每一部設備工作量維持平均,避免其中某一台過載 * 工作可以是外部 traffic / request / API call ,也能來自內部其他服務(例如前端 call 後端) * 如果 Cluster 其中一台伺服器掛了,Load Balancer 要負責把流量都導到健康的其他台上面 * 也能作為提供可擴縮性(Scalability)手段(這裡先不做討論) * 這裡討論由 Web Service 提供的 Load Balancer 幫我們做到的 Load Balancing ### L4 與 L7 的 Load balancing :::info **OSI Layer 示意圖**,但這裡主要介紹的還是只有 L4 與 L7 層的軟體 Load Balancer ![](https://i.imgur.com/FpFiebP.jpg) > 圖片來源:[Load balancing in Layer 4 vs Layer 7 with HAPROXY Examples - YouTube](https://www.youtube.com/watch?v=aKMLgFVxZYk&t=180) ::: * Layer 4 傳輸層資訊的分配機制 * 以實體的對外 IP 或 Virtual IP(VIP) 接收請求,再由 Load Balancer 做負載平衡 * 看 Source IP / port 或 Destination IP / port * Source: IP Hash(下面會介紹)、Destionation: 轉傳至特定機器 :::info 延伸閱讀: [九個硬體負載平衡器優於軟體負載平衡器的理由](https://blog.avinetworks.com/f5-vs-avi-networks) ::: * Layer 7 應用層資訊的分配機制 * 在 L4 的基礎之上 * 看請求內容 (URL, Cookie, Header) 來做 Load Balancer * 例如:在 Nginx 設定反向代理 (Reverse Proxy),讓 `http://example.com/app1 -> http://10.0.0.1:8080` 和 `http://example.com/app2 -> http://10.0.0.2:8080` :::info * **Layer 7** * 某些會有能力進行 SSL 加解密 * 除了負載平衡,某些也常被當作網路防火牆 (Web Application Firewall),阻絕外人直接存取內網資源 > BT 補充:有公司會額外買處理 SSL 的機器 (SSL 加速器) * **Proxy** * 外網是在 Proxy 與 Server 之間 * 內網是在 Proxy 與 Client 之間 * Caching * 假設內網的使用者請求的頁面在 Proxy 有暫存,可以直接回給使用者 * 好處: 減少外部流量,節省頻寬,加快回應速度 ![](https://i.imgur.com/IGUWvXD.png) * **Reverse proxy** * 外網是在 Proxy 與 Client 之間 * 內網是在 Proxy 與 Server 之間 * Caching * 假設外網的使用者請求的頁面在 Proxy 有暫存,可以直接回給使用者 * 好處: 減少 Server 負擔 * 但本章節的 Reverse Proxy 只有做到代理,而無暫存 * Client 只需與 Reverse Proxy 溝通,再由 Reverse Proxy 決定如何分配給 Server * 若 Server 調整設定後只需通知 Proxy,而使用者則不需知道任何更動 * Ex. 更換內網 IP or Port ![](https://i.imgur.com/uO7cFxP.png) > BT 補充:有個軟體叫 Varnish ,是很強的 reverse cache proxy ::: * 使用者端 * 給一個 server list 讓使用者端決定要連哪個伺服器 * DNS-based Load balancing * 根據來源 IP 的不同,發給你不同的 IP 產生 Load Balancing * 或一次回給你很多 IP,依照實作方式的不同(亂數或以第一個為主),達成 Load Balancing :::info 用 `host google.com` 看到的 IP 會根據不同來源位置,而產生不一樣的結果 ::: ### 在 L4 實作 Load Balance 方法 > 本節圖片來源:[Linux伺服器叢集系統(三)--LVS叢集中的IP負載平衡技術 | linux-vs.org (簡體中文)](http://www.linuxvirtualserver.org/zh/lvs3.html) :::info **Virtual IP** Virtual IP 為 Virtual Router Master 負責持有的IP ::: * NAT 模式 * Load balancer 收到 Client 的要求後,修改封包 Header * Load balancer,再將要求轉送給後端的其他伺服器處理 * 後端處理完要求後回給 Load Balancer * Load Balancer 收到後端的封包,修改封包 Header 後,再轉送給 Client * 缺點:容易造成 Load Balancer 過載 ![](https://i.imgur.com/kH4NMEB.jpg) * 封包修改範例 1. 連入封包 `SOURCE 202.100.1.2:3456 DEST 202.103.106.5:80` 2. Load balancer 改完轉傳給 real server `SOURCE 202.100.1.2:3456 DEST 172.16.0.3:8000` 3. 後端伺服器回覆給 Load balancer `SOURCE 172.16.0.3:8000 DEST 202.100.1.2:3456` 4. Load balancer 再回給使用者 `SOURCE 202.103.106.5:80 DEST 202.100.1.2:3456` * IP 隧道模式 (IP Tunneling) > IP 隧道經常用於連接兩個不是用路由直接連結的 IP 網路 Load Balancer 與 Real Server 的 IP 都必須是 Public IP Load Balancer 與 Real Server 都擁有相同的 VIP * Load balancer 先收到 Client 的要求,再根據演算法選出適合的後端伺服器 * Load balancer 將請求封包封裝 (encapsulation) 在另一個 IP 封包中,再將封裝後的 IP 封包轉送給選出的後端伺服器 * Real Server 處理完要求後再將回應封包直接返回給 Client ![](https://i.imgur.com/oy81Ook.gif) ![](https://i.imgur.com/mzxTdXQ.jpg) * Direct Routing Mode (DR) > Load Balancer 與 Real Server 位於相同的區域網路底下 * Load balancer 收到 Client 的要求後 * 將資料封包的 MAC 地址改為選出後端伺服器的 MAC 地址,再將修改後的資料封包傳給後端伺服器組成的區域網路 * 該負責的伺服器直接回應 Client 而不經過主伺服器。這樣效能比較不會卡在主伺服器上 :::info Real server 與 Load balancer 同時擁有相同的 VIP。但只有 Load balancer 設定的 VIP 地址是對外的;並且 Real Server 把 ARP 關閉,這裡的 VIP 對外部是不可見的,只是用於處理目標地址為該 VIP 的要求。 ::: ![](https://i.imgur.com/879KbED.gif) ![](https://i.imgur.com/kaCjRwx.jpg) | | NAT | TUNNEL | DR | | - | - | - | - | | Server | any | Tunneling | Non-arp device | | Server Network | private | LAN/WAN | LAN | | Server Connection | low (10~20) | High (100) | High (100) | | Server Gateway | load balancer | own router | own router | ### 常見的排程演算法 / 規則 [Comparing Load Balancing Algorithms - YouTube](https://youtu.be/iqOTT7_7qXY?t=54) 以下圖片來自這很棒的影片動畫圖解 * 隨機 * 循環法 (round-robin) * 大家公平輪流 ![](https://i.imgur.com/0LnTipd.jpg) * 加權循環法 (weighted round-robin) * 有其中一個人能力大於其他人時,能者多勞 * 例如有時候備用伺服器用弱一點的機器 ![](https://i.imgur.com/Ch26tYN.jpg) * 最少連線數 (least connections) * 當 Server 2 的使用者待在線上特別久,而 Server 1 已經沒人用了 * 再繼續輪流塞人的話,Server 2 會超忙,Server 1 超閒 ![](https://i.imgur.com/PmLZelq.jpg) ![](https://i.imgur.com/kp6ADju.jpg) * 基於局部性 (locality-based) * 最少連線數(Locality-Based Least Connections) * 找出該 IP 最近使用的伺服器 * 伺服器可用就直接發送請求 * 若不存在或超載,就以「最少連線數」的原則,選出可用的伺服器 * 備援式的最少連線數(Locality-Based Least Connections with Replication) * 找出該 IP 最近使用的伺服器組 * 以「最少連線數」的原則從伺服器組中選出伺服器 * 若伺服器組中的伺服器皆超載,則從其他未加入組的伺服器中,選出伺服器,並加入到伺服器組中 * 若經過一段時間後,組內有伺服器閒置,則該伺服器會被移出,用以提高叢集效率 > 參考資料:http://kb.linuxvirtualserver.org/wiki/IPVS * 各種基於雜湊的 (Hash-based) * 可能會看的東西(取決於是第幾層) * 使用者請求的 URL * Protocol 種類 * 來源位址 * 目的地位址 ### sticky / persistent session > sticky session 必要性:1. stateful 2. 且 session 存在 server,沒在任何 share database * 例如:登入狀態 * 同一個 session 盡量導到同一台機器上 * 用 source address / cookie 決定要分給哪台 * 那台機器中途死掉了怎麼辦 * 架構設計成讓其他資料庫 (ex: redis, memcache) 記住 session,再同步給 server * 或把資訊存在 client * 改成 stateless 的方式,降低對 sticky session 的依賴 ## 常見的 Load Balancer 軟體(或硬體) ### 硬體 #### F5 Big-IP #### Citrix Netscaler #### Radware ### 軟體 #### Linux Virtual Server * 運作在 TCP/IP 架構中的第 4 層(傳輸層) * 能設定的參數比較少,但因為沒有可太多設定的東西,可以減少人為出錯的機率 * 除了對 Web Server 做負載平衡外,也可以對 MySQL 做負載平衡 * 實作於[期末專題報告](https://github.com/NCNU-OpenSource/hanetdb) #### Nginx * 運作在 TCP/IP 架構中的第 7 層(應用層),可以針對 HTTP 應用做一些分流的策略,比如針對域名、目錄結構 * 安裝與設定較為簡單易懂,測試起來較為方便 * 僅支援 HTTP, HTTPS, E-mail,應用範圍較小 * 預設有三種 Load Balance 方法,Round Robin、weight 以及 ip_hash #### HAProxy * 做為 TCP 和 HTTP 應用程式的 high availability load balancer 和 proxy server * 可以實作 L4 或 L7 load balancer * HAProxy 可以對 MySQL 進行負載平衡,對後端的資料庫進行檢測和負載平衡。 <!-- > FIXME: 擴張啥 rephrasing > 他有啥特性,他超強 C100K > L4 能用什麼模式,L7 支援什麼應用 > session 量 > throughput 量 --> ## 常見的 High Availability 軟體 #### Keepalived * 提供 Load Balancing 的故障隔離與故障轉移 * 部署和使用非常的簡單,所有設定只需要一個設定檔即可以完成 * 用 Linux Virtual Server IPVS kernel module 來實作的 * 實作了 VRRP 協定 #### Heartbeat * Heartbeat 2.1.4 後拆分成 3 個子專案,安裝與使用比較複雜 <!-- 功能更強大,配套工具更全,適合做大型叢集管理 (編按: Citation needed) --> ##### VRRP 協定 ![](https://i.imgur.com/JJHnbCp.png) > 圖片來源: [Red Hat Enterprise Linux 7 Load Balancer 管理 | Red Hat](https://access.redhat.com/documentation/zh-tw/red_hat_enterprise_linux/7/pdf/load_balancer_administration/Red_Hat_Enterprise_Linux-7-Load_Balancer_Administration-zh-TW.pdf), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/ "Creative Commons — Attribution-ShareAlike 3.0 Unported — CC BY-SA 3.0") * Virtual Router Redundancy Protocol,虛擬路由器備援協定 * RFC2338, 3768, [5798](https://datatracker.ietf.org/doc/html/rfc5798) * 虛擬路由器: 一個抽象的物件,有一個辨識號碼(VRID)和一組相關聯的 IP 位址(Virual IP, VIP) * 一個虛擬路由器底下有很多 VRRP 路由器,同 VRID 的成為同一群組 * VRRP 路由器可以分為:主控制路由器(master)與備援路由器(backup) * 會根據 priority 選其中一個 VRRP 路由器來作為 master,剩下是 backup * 對外有一個虛擬 IP (VIP),跟 master 產生關聯 (associate) * 只有 master 會回覆想問 VIP 是誰的 ARP 請求 * 若是 master 掛掉了,則從 backup 中依優先權再選出一個成為 master,是個 **Failover** 動作 * master 會定期 multicast 發送 ADVERTISEMENT * 若 backup 一段時間沒聽到 ADVERTISEMENT,就知 master 掛了 <!-- > 步驟這麼多,做個流程圖 UML --> ![](https://i.imgur.com/cb3jX2N.png) > 圖片來源: [Best Practices for Floating IP Addresses | Compute Engine 說明文件](https://cloud.google.com/solutions/best-practices-floating-ip-addresses#example_use_case_for_migration), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0) ### DEMO * 主要架構 ![](https://i.imgur.com/z6gqR2o.png =400x) * 摘要 * ![DigitalOcean Referral Badge](https://web-platforms.sfo2.digitaloceanspaces.com/WWW/Badge%202.svg) [BT 的 Digital Ocean 邀請連結,你能夠獲得 100 美元的額度,而 BT 能夠獲得 25 美元的額度!還不快點加入!](https://m.do.co/c/7a14e0e84052) (需要信用卡才能註冊) * 這裡我們用 Keepalived 軟體,以監控叢集成員與叢集服務,並使用 Nginx 作為軟體的 Load Balancer * 本次 DEMO 利用 DigitalOcean 提供的 Float IP API 作為分配 Virtual IP 的手段 * 附註: 在 AWS 也有 Elastic IP 能使用 * 本次 DEMO 總共用到四台虛擬機,兩台前端用來做 Load Balance 以及 Failover,兩台後端用來做 Application Server * 建立虛擬機 * 先建立 droplet 這邊選擇 Ubuntu 18.04 ![](https://i.imgur.com/KXAnHJs.png =1020x) * 選最便宜的 ![](https://i.imgur.com/xiodt4D.png) * 選亞洲伺服器這樣延遲比較低 ![](https://i.imgur.com/tDJwnYP.png) * 選擇登入時的驗證方式,這邊自由隨意~~但是他密碼的要求有夠多~~ ![](https://i.imgur.com/zPjp5V0.png) * 這邊可以直接建立四台虛擬機 ![](https://i.imgur.com/Kps5urk.png) * 接下來直接透過 ssh 連入虛擬機 * 後端 * nginx ```=shell sudo apt-get update sudo apt-get install nginx ``` * 修改首頁方便我們辨識 ```=shell sudo vim /var/www/html/index.nginx-debian.html ``` * 全部刪掉然後打上 * 第一台 ```=html5 <h1>Primary</h1> ``` * 第二台 ```=html5 <h1>Secondary</h1> ``` * 前端 * keepalived * 首先安裝 nginx ```=shell sudo apt-get update sudo apt-get install nginx ``` * 直接修改預設設定 ```=shell sudo vim /etc/nginx/sites-available/default ``` * 新增 load balance 的設定 ```=shell upstream backend { server first_web_server_ip:80; server second_web_server_ip:80; } server { location / { proxy_pass http://backend.example.com; } } ``` :::info ``first_web_server_ip``,``second_web_server_ip``,``http://backend.example.com`` 都是要修改的地方 ::: * 安裝 keepalived ```=shell sudo apt install keepalived ``` * 接下來開始建立設定檔 ```=shell sudo vim /etc/keepalived/keepalived.conf ``` * on Primary :::info ``MASTER_private_IP``,``BACKUP_private_IP``,``password`` 都是要修改的地方 ::: ```=shell vrrp_script chk_nginx { script "pgrep nginx" # 檢查 nginx 是否有在行程 (Process) 中 interval 2 } vrrp_instance VI_1 { interface eth1 # 選擇網路介面卡 state MASTER # 宣告身分 (MASTER OR BACKUP) priority 200 # 優先權 virtual_router_id 33 # Keepalived 用來識別是否為同一個群組 unicast_src_ip MASTER_private_IP # 用來多播 (multicast) 的來源 IP unicast_peer { BACKUP_private_IP # 接收來自哪裡多播 (multicast) 的IP } authentication { auth_type PASS # 驗證方式 auth_pass password # 驗證密碼 } track_script { # 追蹤服務是否正常 (health check) chk_nginx } notify_master /etc/keepalived/master.sh # 當前節點成為 master 時,執行腳本 } ``` * on Secondary * Secondary 的地方也要喔,注意兩邊的 IP 互換 ```=shell vrrp_script chk_nginx { script "pgrep nginx" interval 2 } vrrp_instance VI_1 { interface eth1 state BACKUP priority 100 virtual_router_id 33 unicast_src_ip BACKUP_private_IP unicast_peer { MASTER_private_IP } authentication { auth_type PASS auth_pass password } track_script { chk_nginx } notify_master /etc/keepalived/master.sh } ``` * 接下來下載 DigitalOcean 提供的 Python script ```=shell cd /usr/local/bin sudo curl -LO http://do.co/assign-ip ``` * 建立 Float IP * 在 DigitalOcean 的設定頁面選擇 Networking -> Floating IPs </br>選擇剛剛建立的 Primary 後按下 Assign Float IP :::info 申請 Float IP 的用意,是讓使用者透過這個另外申請、能變更綁定 Server 的 Virtual IP 來存取服務,而不是直接去造訪兩台的 Real IP ::: * 建立 DigitalOcean API Token * 在 DigitalOcean 的設定頁面選擇 API , 按下 Generate New Token * 取個名字,然後就可以建立了 * 建立完的 Token 只會出現這一次,所以我們先複製起來 * 回到虛擬機,建立當主機掛掉時需要執行的腳本 * `DO_TOKEN` 變數要改成上一步拿到的 API Token * `IP` 變數要改成上一步拿到的 Floating IP ```=shell sudo vim /etc/keepalived/master.sh ``` :::info 這個腳本由 DigitalOcean 提供,用意是當某一台 Real Server 變成 Master state 的時候,會去檢查自身是否擁有 Floating IP,如果沒有就去跟 DO 要求將 Floating IP 導向自身 ::: ```=shell #!/bin/bash export DO_TOKEN='digitalocean_api_token' IP='floating_ip_addr' ID=$(curl -s http://169.254.169.254/metadata/v1/id) HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active) if [ $HAS_FLOATING_IP = "false" ]; then n=0 while [ $n -lt 10 ] do python /usr/local/bin/assign-ip $IP $ID && break n=$((n+1)) sleep 3 done fi ``` ::: warning 先確定你的機器裡有安裝 Python 了,以及 Python requests module,因為這個 script 需要用到 `sudo apt install python python-requests` ::: * 接下來讓 ``master.sh`` 可以被 keepalived 執行 ```=shell sudo chmod +x /etc/keepalived/master.sh ``` * 可以來啟動我們的 keepalived 了 ```=shell sudo systemctl start keepalived ``` * 測試當 Nginx 故障 (Testing Nginx Failure) * 在 Primary 上輸入 ```=shell sudo service nginx stop ``` * 在數秒後 keepalived 將會把 Float IP 交給 Secondary * 在 Primary 上輸入 ```=shell sudo service nginx start ``` * 在數秒後 keepalived 將會把 Float IP 交給 Primary * 測試當伺服器故障時 (Testing Server Failure) * 在 Primary 上輸入 ```=shell sudo reboot ``` * 在數秒後 keepalived 將會把 Float IP 交給 Secondary * 在 Primary 開機完成數秒後 keepalived 將會把 Float IP 交給 Primary ## References [High-Availability Computer System in 1991](https://jimgray.azurewebsites.net/papers/ieee_HA_Swieorick.pdf) [Introduction to High Availability | Linode](https://www.linode.com/docs/guides/introduction-to-high-availability/) [High Availability tutorials, questions and resources | DigitalOcean](https://www.digitalocean.com/community/tags/high-availability) [Introduction to High Availability | Fusion Middleware High Availability Guide](https://docs.oracle.com/cd/A91202_01/901_doc/rac.901/a89867/pshavdtl.htm) [Overview of High Availability ](https://docs.oracle.com/database/121/HAOVW/overview.htm#HAOVW113) [Load Balancing | Administration Guide | SUSE Linux Enterprise High Availability Extension 15](https://documentation.suse.com/sle-ha/15-GA/html/SLE-HA-all/cha-ha-lb.html) [Synology High Availability White Paper](https://global.download.synology.com/download/Document/Software/WhitePaper/Package/HighAvailability/All/enu/Synology_SHA_White_Paper.pdf) [SLA服務可用性4個9是什麼意思?如何保證服務的高可用性 HA(High Availability)?_Kotlin 開發者社群 - MdEditor](https://www.gushiciku.cn/pl/pLMh/zh-tw) [高有效性 (High Availability) 初論 30 講 :: 2011 iT 邦幫忙鐵人賽](https://ithelp.ithome.com.tw/users/20000065/ironman/279) [HAProxy document](http://cbonte.github.io/haproxy-dconv/2.3/intro.html#3) [雲端服務品質不卡住?連 Google、微軟都在用的 SLA 你不能不懂! | TechOrange](https://buzzorange.com/techorange/2013/05/21/service-level-agreement-sla/) [之前 LSA 講如何建立 Cluster - Corosync and Pacemaker](https://hackmd.io/G0DdQLAiSemZv_sMbDagQg#The-way-to-create-the-cluster-Computing) [之前 LSA 講如何建立 Cluster - HAProxy](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2FxhFa9y3TQLCsYrL2WMOK5A) [MySQL 高可用方案及成功案例](https://www.slideshare.net/fanndywang/mysql-28141817) [章 2. Keepalived 總覽 Red Hat Enterprise Linux 7 | Red Hat Customer Portal](https://access.redhat.com/documentation/zh-tw/red_hat_enterprise_linux/7/html/load_balancer_administration/ch-keepalived-overview-vsa) https://www.keepalived.org/ [External HTTP(S) Load Balancing overview  |  Google Cloud](https://cloud.google.com/load-balancing/docs/https) 好多漂亮的圖解可以拿來用 [High Availability Cluster: Concepts and Architecture | NetApp](https://cloud.netapp.com/blog/cvo-blg-high-availability-cluster-concepts-and-architecture) 參考 Cluster 架構來自這 [Server Load Balancing – 阿喵就像家](https://mlwmlw.org/2011/04/server-load-balancing/) [國家教育研究院雙語詞彙、學術名詞暨辭書資訊網](https://terms.naer.edu.tw/) 避免使用支語,有英文轉中文的專有名詞都來查一下 [搜尋和下載國際詞彙 - Microsoft | 語言入口網站](https://www.microsoft.com/zh-tw/language/) 查台灣軟體技術用語的另一個好東西,雖然是 M 開頭,BT 別打我 OAO [make 簡單介紹](http://linux.vbird.org/linux_basic/0520source_code_and_tarball.php#intro_make) [make 簡單介紹2](https://www.cnblogs.com/tinywan/p/7230039.html) [libssl-dev](https://blog.csdn.net/WANG__RONGWEI/article/details/54898410) [build-essential](https://www.ubuntu-tw.org/modules/newbb/viewtopic.php?post_id=37689) [Module ngx_stream_upstream_module](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#server) [Docker 容器的健康检查 - 张志敏的技术专栏](https://beginor.github.io/2018/03/11/healthy-check-instruction-of-docker.html) [Important Health Checks for your MySQL Master-Slave Servers](https://scalegrid.io/blog/important-health-checks-for-your-mysql-master-slave-servers/) [叢集檔案系統 - 維基百科,自由的百科全書](https://zh.wikipedia.org/wiki/%E9%9B%86%E7%BE%A4%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F) [proxy & reverse proxy](https://www.jyt0532.com/2019/11/18/proxy-reverse-proxy/) [三種 LVS 的模式:LVS-NAT、LVS-TUN、LVS-DR](https://blog.maxkit.com.tw/2016/05/lvs-lvs-natlvs-tunlvs-dr.html) [How To Set Up Highly Available HAProxy Servers with Keepalived and Floating IPs on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-highly-available-haproxy-servers-with-keepalived-and-floating-ips-on-ubuntu-14-04) #### 延伸閱讀 * L2 load balance: Link Aggregation * Cloudflare Anycast 原理概述於[期末專題報告](https://github.com/NCNU-OpenSource/hanetdb) * router multipath * [Introduction to modern network load balancing and proxying | by Matt Klein | Envoy Proxy](https://blog.envoyproxy.io/introduction-to-modern-network-load-balancing-and-proxying-a57f6ff80236) 介紹近代(文章寫作於 2018 年)的負載平衡,[中文翻譯 by Neil's Note](https://qazwsxedccsqzse.blogspot.com/2018/06/blog-post.html) * 裡面提到了 Google, Facebook, GitHub 各自有 open source 自己開發的 L4 Load balancer,我還好奇另外去查到 [LINE 自己開發的](https://speakerdeck.com/line_devday2019/software-engineering-that-supports-line-original-lbaas) * [binhnguyennus/awesome-scalability | GitHub](https://github.com/binhnguyennus/awesome-scalability#availability) 的 Availability 大標 * [分散式資料庫系統上的問題探討 (Web Archive)](https://web.archive.org/web/20220818072702/http://120.105.184.250/lwcheng/Kid51/kidpps/Kid51_CHAP14.pdf) [(原址已失效)](http://120.105.184.250/lwcheng/Kid51/kidpps/Kid51_CHAP14.pdf) by [Frank S.C. Tseng ](http://www2.nkfust.edu.tw/~imfrank) * [Google - Site Reliability Engineering](https://sre.google/books/) * [Improving load balancing with a new consistent-hashing algorithm | by arodland | Vimeo Engineering Blog | Medium](https://medium.com/vimeo-engineering-blog/improving-load-balancing-with-a-new-consistent-hashing-algorithm-9f1bd75709ed) * DNS-based Load Balancing - [EDNS Client Subnet](https://web.archive.org/web/20140702174224/http://www.afasterinternet.com/howitworks.htm)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully