# 2022/12/02 Report --- - Fast API - CAP theorem - BASE - acid - transactions - n+1 problem - microservice - Docker --- ## Fast API ---- ## TL;DR Fast API 是用來開發 `RESTful APIs` 的常用框架,與其他Python的框架 Flask 、 Django 相同,可以用來建立 API 及網頁服務 ---- ## 特點 - **Fast**: 超高的效能與 **NodeJS** and **Go** 不相上下 - **Fast to code**: 提高開發新功能的速度 200% 至 300% - **Fewer bugs**: 減少約 40% 人為導致的錯誤 - **Intuitive**(直覺): 許多IDE都有支援,處處都有自動完成。 ---- - **Easy**: 易於使用、學習(官方說的 - **Short**: 減少撰寫重複的程式。 在 declare parameter 可以指定多種功能。 - **Robust**(可靠的): Get production-ready code. 自動化生成 API 文件 - **Standards-based**: Based on (and fully compatible with) the open standards for APIs: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (previously known as Swagger) and [JSON Schema](https://json-schema.org/). ---- ## 其他酷酷的功能 ---- ### short 所有的一切都有預設值,但也提供許多 optional 的選項,所有參數都可以進行微調。在不做任何設定時,所有功能都會是可以正常運作ㄉ! ---- ### Validation 會自動驗證所有進出的資料,確保資料型別正確! ---- ### Dependency Injection (依賴注入) - dependencies can have dependencies - All **automatically handled** by the framework. - 強大的自動驗證功能 ---- ## 帶大家逛逛我們的code(? --- ## CAP theorem ---- ### 前情提要: - 這個系統有一個小資料庫 - 資料庫升級(更多的RAM、更多的空間) - 遇到了瓶頸 - 加一個新的資料庫幫忙分擔流量 - 不論哪個資料庫有更新,它都會將資料同步給對方。使用者不需改變原有行為,但現在我們能處理兩倍的流量!(分散式系統) ---- ![](https://i.imgur.com/Q1TI1H9.png) ---- ### 問題: 有天資料庫間的網路連線發生了些問題。導致資料在傳輸過程中丟了,或是網路直接斷了等等。 ---- ### 假設: 若我們今天有3個資料庫,A, B在台北,C在台中。有位使用者連線到A更新了某筆資料,同地區的B也順利地同步了,但要同步到C時發現台北到台中的網路出了,導致資料不再一致。若這位使用者下次使用時,連線到C,則會發現之前更新的資料不見了。 #### 而CAP theorem就是在探討這個議題。 ---- - 一致性(**C**onsistency) - 可用性(**A**vailability) - 分區容錯性(**P**artition tolerance) ---- - 一致性(**C**onsistency) - client - client 操作時能夠獲取最新寫入的結果 ---- - 可用性(**A**vailability) - client - 不能超時、不能出錯,獲取的資料是合理的(但結果有可能因為資料尚未同步完整or延遲,導致資料是不正確的) ---- - 分區容錯性(**P**artition tolerance) - 分區 - 就算網路出現問題導致資料分區,整個系統仍然要可以繼續運作 - 選擇如何去影響 client 感知到的「一致性」和「可用性」 --- DEF: > C3取2 - CAP 理論探討的分散式系統,強調:interconnected 和 share data - ex.MySQL --- ### CP vs AP - 無法確保網路不出問題,P必選 ### CAP 關注的是資料,而不是整個系統 - 我們需要將系統內的資料按照不同的應用場景和要求進行分類 - 用戶管理系統包含用戶賬號資料(用戶 ID、密碼) -> CP - 用戶信息資料(暱稱、興趣、愛好、性別、自我介紹等) -> AP --- - 正常運行情況下,不存在 CP 和 AP 的選擇,可以同時滿足 CA - 放棄並不等於什麼都不做,需要為分區恢復後做準備 --- ## BASE ---- - 基本可用(Basically Available) - 分散式系統在出現故障時,允許損失部分可用性 - 軟狀態(Soft State) - CAP 理論中的資料不一致 - 最終一致性(Eventual Consistency) - 不同的資料能夠容忍的不一致時間是不同的 --- 參考資料 > https://medium.com/%E5%BE%8C%E7%AB%AF%E6%96%B0%E6%89%8B%E6%9D%91/cap%E5%AE%9A%E7%90%86101-3fdd10e0b9a > https://godleon.github.io/blog/Architecture_Design/Architecture-Design-HA-CAP/ --- ## ACID ---- 資料庫管理系統為了保證事務的正確性而提出 ---- - **A**tomicity: - 視一件事務(transaction)為最小單位 - **C**onsistency: - 不同的數據都會有一些基本的約束 - 事務開始之前和事務結束以後,資料庫的完整性沒有被破壞 ---- - **I**solation: - 資料庫允許多筆交易同時進行 - 交易進行時未完成的交易資料並不會被其他交易使用,直到此筆交易完成 - **D**urability事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失 - transaction 成功之後。就算 server 當機、斷電,已經修改的數據也不會不見,應該要被寫入能夠永久儲存的裝置中 ---- A 匯錢給 B,必須要執行兩個步驟 1. A.money -= 100 2. B.money += 100 ---- A 交易:小明 要匯給 小華 100: 1. 小明.money -= 100 2. 小華.money += 100 B 交易:小明 要匯錢給 阿雅 100 1. 小明.money -= 100 2. 阿雅.money += 100 ---- 執行 a.1 的操作,先看到小明有 500$ b.1 也一起執行,也看到小明有 500$ a.1 小明 -100$,然後幫小明標記為 400\$ b.1 也幫小明 -100$,也幫小明標記為 400\$ 小明匯了兩筆錢,結果只扣到一筆的錢 ---- 參考資料 > https://lance.coderbridge.io/2021/04/24/short-what-is-acid/ > https://tw.alphacamp.co/blog/mysql-intro-acid-in-databases --- # Transaction ---- Transaction(中文翻作交易或事務),是資料庫執行過程中的一個「邏輯單位」,一個 transaction 中包含多個對資料庫操作的行為,簡單來說一個transaction,就是一組一連串對資料庫進行Read和Write的動作。 ---- 每個 transaction 有兩種可能的結局: 全部執行成功 or 全部不執行(只要其中一個行為失敗就全部回滾) - 全部SQL執行成功 -> commit; - 只要有一個SQL失敗 -> rollback; 為什麼transaction要這樣設計啊?因為就算沒有全部SQL執行成功,至少他也執行到某個程度了啊,為什麼不要把這部分的成果提交出去呢? Transaction 主要是解決需要一起發生的事件但事件或事件的參與者不同時或不一致的問題。 ---- ### EX: 假如今天到商店去買東西 收銀員刷條碼,告知價格為$728元; 從錢包掏出錢,交給收銀員; 假如在付賬時 發現錢帶不夠 例如我已拿出$500給收銀員時 才發現錢包只剩下$10呢? ---- 這時現實生活中會怎麼做 當然是收銀員會把$500退還給我 然後把商品收回去,重新放回架上 一切當作沒發生過一樣 這樣才合理嘛 ---- 所以database transaction也是這樣設計的。 另外如果只有1個使用者在存取資料庫資料 我們可以不必考慮其他使用者。 然而在可以多使用者&多交易 可同時進行的資料庫系統中 可能有多位使用者 同時修改同一筆資料 因此如何維持資料的正確性和一致性 就是資料庫系統最大的課題。 以上案例,也是說明為什麼transaction必須符合四大特性:ACID。 ACID交給其他人報告囉~~~ --- # N+1 problem(N+1 query) ---- 假設有 User 及 review 兩份表格,使用 user_id 進行關聯,有一個查詢是「找出 20 歲以上使用者的所有評論」 - 執行狀況: 1. 在查詢時,第一次先找出「所有 20 歲以上的使用者」,假設有五筆資料。 2. 接著在這五筆資料裡面,再把評論撈出來,用迴圈把每一個使用者的資料撈出來。 ---- 第一次查詢主要的 User 表格,以查詢到的結果,再查詢有關聯的副表格。 也就是說,第一次查詢出來是 N 個紀錄,實際執行時需要查詢的次數是 N + 1 次(就執行順序來說,1 + N 次比較合理),這就叫做 N + 1 問題。 ---- ### 為什麼會有這個問題? 如果懂SQL的话,就知道,其實用一個 SQL 的 join 就可以了,但是在 ORM 裡面,很有可能會寫出這樣的程式碼。 ---- ### What is ORM ORM(Object-Relational Mapping),意思就是將關聯式資料庫的操作,與物件(Object) 相互映射,目的是讓工程師能夠藉由 ORM 透過操作物件的方式來操作資料庫,提升開發效率。所有與資料庫的語法都是使用ORM的語法,ORM換轉換成SQL去執行,我們就不用自己寫又臭又長的 SQL 了。 ---- ### 解決辦法 SQLAlchemy ORM 的 relationship() 預設使用一種稱為 lazy loding 的技術,只有存取到相關聯的屬性時,才會執行 1 個 SELECT 載入相關連的 models ,如果不了解其原理的話,很容易會有 n+1 query 的問題。 ---- 以SQLAlchemy來說有 - immediate可以在model創建時用額外的 SELECT 語句載入相關聯的 model 資料 - joined 同樣會立即載入相關聯的 model, 但是用 JOIN 語句,而不是額外的 SELECT 等等 --- ## microservice ---- ### microservice微服務 - 一種軟體**架構**的設計方法 - 微服務可將應用程式分解成最小且彼此獨立的元件。有別於**傳統單體式架構**,各自獨立的微服務能共同運作並完成相同的任務,而其中每一項元件或流程,都屬於一種微服務。 ---- ### 傳統單體式架構 - 所有元件都寫在一起,後期開發成本高 - 不同功能的程式碼寫在一起,難以新增、修改功能 ---- ![](https://i.imgur.com/d7aIGCH.png) ---- ## microservice - 將大型應用程式拆解為獨立元件,彼此透過API溝通 - 不同功能的程式碼被拆解,調整單一功能時並不會影響其他功能的運作 ---- ## advantages - **平行擴展**:建置、測試、部署、更新、維運較容易,不會影響其他服務 - **開發流程更快速**:針對個別服務進行修正,或是擴增新的功能 - **開發流程彈性**:可選擇自己的程式語言或套件,技術自由 - **錯誤隔離**:提高系統容錯率 ---- ## microservice disadvantages - 開發時需要注意的事項變多(ex: API沒有定義清楚,或是元件拆分的方式不佳,都會導致整個系統產生很多問題) - 伴隨微服務而來的複雜性、運轉部件和相依關係大幅增加,因此需要DevOps的幫助 ---- ## why we need microservice? - 為了能更**快速**回應市場需求,優化服務內容,提供高品質的軟體 - 而這些**可獨立部署**的微服務適合用於agile開發 ---- ## microservice example ---- ![](https://i.imgur.com/nIP1vCp.png) --- ## Container ---- ### What is Container? ---- #### 輕量級的虛擬化技術 - 作業系統層虛擬化(Operating System–Level Virtualization) - 容器技術是將應用系統相關的程式碼、函式庫、執行環境配置打包成隔離的可執行沙盒環境 ---- 在較大型的應用程式部署中,可將多個 Container 部署為一或多個 Container 叢集。這類叢集可能由 Container Orchestrator 管理,例如 Kubernetes。 ---- ### Container 的優點 - 所需的系統資源較少:Container不含作業系統的image - 可攜性更高/跨平台開發:執行的應用程式可輕鬆部署到不同的作業系統 - 作業更一致:無論應用程式部署在何處,Container中的應用程式都會執行相同的作業。 - 效率更高:Container可讓應用程式更快速地部署、修補或擴充。 ---- ## Image ---- ### What is Image? ---- 映像檔是一個模版,讓Container知道要基於怎樣的設定和內容來建立一個新容器。 例如:一個映像檔裡可以包含一個完整的 MySQL 服務、一個 Golang 的編譯環境、或是一個 Ubuntu 作業系統。 --- ## Docker - 供使用者快速建立、部署和測試應用程式的平台 - 將一套應用程式所需的執行環境打包起來,建立一個孤立環境,方便在不同的硬體中移動 - 符合微服務的運作原理 ---- ### 特點 - 輕量化,規模相當小 - 執行速度比虛擬機快(秒級與分鐘級的區別) - 在Windows上有夠難裝(一切都是WSL2害的) --- ## END ~~
{"metaMigratedAt":"2023-06-17T15:49:23.835Z","metaMigratedFrom":"YAML","title":"2022/12/02 Report","breaks":true,"lang":"zh-tw","slideOptions":"{\"transition\":\"slide\",\"theme\":\"solarized\"}","contributors":"[{\"id\":\"ab1b9a7e-f184-4486-a8d4-a4431acd03d2\",\"add\":775,\"del\":9},{\"id\":\"dacf2091-9992-4f5d-a557-c499f1dd5d55\",\"add\":5428,\"del\":116},{\"id\":\"dbd3c3f6-7099-483f-b85b-2d0c22ec4ddb\",\"add\":413,\"del\":87},{\"id\":\"ff25936e-3d12-40ca-9fd0-f1fc893ea090\",\"add\":325,\"del\":1}]"}
    229 views
   Owned this note