<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] 日志可能是一種最簡單的不能再簡單的存儲抽象,只能追加、按照時間完全有序(`totally-ordered`)的記錄序列。日志看起來的樣子: [![](https://box.kancloud.cn/2015-08-28_55dfffd80f5ac.png)](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/images/log.png) 在日志的末尾添加記錄,讀取日志記錄則從左到右。每一條記錄都指定了一個唯一的順序的日志記錄編號。 日志記錄的次序(`ordering`)定義了『時間』概念,因為位于左邊的日志記錄表示比右邊的要早。 日志記錄編號可以看作是這條日志記錄的『時間戳』。 把次序直接看成是時間概念,剛開始你會覺得有點怪異,但是這樣的做法有個便利的性質:解耦了 時間 和 任一特定的物理時鐘(`physical clock`)。 引入分布式系統后,這會成為一個必不可少的性質。 ***【譯注】***?分布式系統的 時間、次序、時鐘是個最基礎根本的問題,詳見被引用最多的*Leslie Lamport*的論文***Time Clocks and the Ordering of Events in a Distributed System***([中文翻譯](http://duanple.blog.163.com/blog/static/709717672012920101343237/)),現在先?***不要***?去看,除非讀完本文后你還是有很興趣要探個明白! 日志記錄的內容和格式是什么對于本文討論并不重要。另外,不可能一直給日志添加記錄,因為總會耗盡存儲空間。稍后我們會再回來討論這個問題。 所以,日志 和 文件或數據表(`table`)并沒有什么大的不同。文件是一系列字節,表是由一系列記錄組成,而日志實際上只是一種按照時間順序存儲記錄的數據表或文件。 討論到現在,你可能奇怪為什么要討論這么簡單的概念?只能追加的有序的日志記錄究竟又是怎樣與數據系統生產關系的? 答案是日志有其特定的目標:它記錄了什么時間發生了什么事情。而對分布式數據系統,在許多方面,這是要解決的問題的真正核心。 不過,在我們進行更加深入的討論之前,讓我先澄清有些讓人混淆的概念。每個程序員都熟悉另一種日志記錄的定義 —— 應用使用`syslog`或者`log4j`寫入到本地文件里的無結構的錯誤信息或者追蹤信息。為了區分,這種情形的稱為『應用日志記錄』。 應用日志記錄是我說的日志概念的一種退化。兩者最大的區別是:文本日志意味著主要用來方便人去閱讀,而構建我所說的『日志(`journal`)』或者『數據日志(`data logs`)』是用于程序的訪問。 (實際上,如果你深入地思考一下,會覺得人去閱讀某個機器上的日志這樣的想法有些落伍過時了。 當涉及很多服務和服務器時,這樣的做法很快就變得難于管理, 我們的目的很快就變成 輸入查詢 和 輸出用于理解多臺機器的行為的圖表, 因此,文件中的字句文本 幾乎肯定不如 本文所描述的結構化日志 更合適。) ## [](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1-what-is-a-log.md#數據庫中的日志)數據庫中的日志 我不知道日志概念的起源 —— 可能就像二分查找(`binary search`)一樣,發明者覺得太簡單了而不是一項發明。早在`IBM`的[系統R](http://www.cs.berkeley.edu/~brewer/cs262/SystemR.pdf)出現時候日志就出現了。 在數據庫里的用法是在崩潰的時候用它來保持各種數據結構和索引的同步。為了保證操作的原子性(`atomic`)和持久性(`durable`), 在對數據庫維護的所有各種數據結構做更改之前,數據庫會把要做的更改操作的信息寫入日志。 日志記錄了發生了什么,而每個表或者索引都是更改歷史中的一個投影。由于日志是立即持久化的,發生崩潰時,可以作為恢復其他所有持久化結構的可靠來源。 隨著時間的推移,日志的用途從`ACID`的實現細節成長為數據庫間復制數據的一種方法。 結果證明,發生在數據庫上的更改序列 即是 與遠程副本數據庫(`replica database`)保持同步 所需的操作。?`Oracle`、`MySQL`?和`PostgreSQL`都包括一個日志傳送協議(`log shipping protocol`),傳輸日志給作為備庫(`Slave`)的復本(`replica`)數據庫。?`Oracle`還把日志產品化為一個通用的數據訂閱機制,為非`Oracle`數據訂閱用戶提供了[`XStreams`](http://docs.oracle.com/cd/E11882_01/server.112/e16545/xstrm_intro.htm)和[`GoldenGate`](http://www.oracle.com/technetwork/middleware/goldengate/overview/index.html),在`MySQL`和`PostgreSQL`中類似設施是許多數據架構的關鍵組件。 正是由于這樣的起源,機器可識別的日志的概念主要都被局限在數據庫的內部。日志作為做數據訂閱機制的用法似乎是偶然出現的。 但這正是支持各種的消息傳輸、數據流和實時數據處理的理想抽象。 ## [](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1-what-is-a-log.md#分布式系統中的日志)分布式系統中的日志 日志解決了兩個問題:更改動作的排序和數據的分發,這兩個問題在分布式數據系統中更是尤為重要。 協商達成一致的更改動作的順序(或是協商達成不一致做法并去做有副作用的數據拷貝)是分布式系統設計的核心問題之一。 分布式系統以日志為中心的方案是來自于一個簡單的觀察,我稱之為**狀態機復制原理**(`State Machine Replication Principle`): **如果兩個相同的、確定性的進程從同一狀態開始,并且以相同的順序獲得相同的輸入,那么這兩個進程將會生成相同的輸出,并且結束在相同的狀態。** 聽起來有點難以晦澀,讓我們更加深入的探討,弄懂它的真正含義。 [確定性](http://en.wikipedia.org/wiki/Deterministic_algorithm)(`deterministic`)意味著處理過程是與時間無關的,而且不讓任何其他『帶外數據(`out of band`)』的輸入影響處理結果。 例如,如果一個程序的輸出會受到線程執行的具體順序影響,或者受到`getTimeOfDay`調用、或者其他一些非重復性事件的影響,那么這樣的程序一般被認為是非確定性的。 進程***狀態***?是進程保存在機器上的任何數據,在進程處理結束的時候,這些數據要么保存在內存里,要么保存在磁盤上。 當碰到以相同的順序輸入相同的內容的情況時,應該觸發你的條件反射:這個地方要引入日志。 下面是個很直覺的意識:如果給兩段確定性代碼相同的日志輸入,那么它們就會生產相同的輸出。 應用到分布式計算中就相當明顯了。你可以把用多臺機器都執行相同事情的問題化簡為實現用分布式一致性日志作為這些處理的輸入的問題。 這里日志的目的是把所有非確定性的東西排除在輸入流之外,以確保處理這些輸入的各個復本(`replica`)保持同步。 當你理解了這個以后,狀態機復制原理就不再復雜或深奧了:這個原理差不多就等于說的是『確定性的處理過程就是確定性的』。不管怎樣,我認為它是分布式系統設計中一個更通用的工具。 這樣方案的一個美妙之處就在于:用于索引日志的時間戳 就像 用于保持副本狀態的時鐘 —— 你可以只用一個數字來描述每一個副本,即這個副本已處理的最大日志記錄的時間戳。 日志中的時間戳 一一對應了 副本的完整狀態。 根據寫進日志的內容,這個原理可以有不同的應用方式。舉個例子,我們可以記錄一個服務的輸入請求日志,或者從請求到響應服務的狀態變化日志,或者服務所執行的狀態轉換命令的日志。 理論上來說,我們甚至可以記錄各個副本執行的機器指令序列的日志 或是 所調用的方法名和參數序列的日志。 只要兩個進程用相同的方式處理這些輸入,這些副本進程就會保持一致的狀態。 對日志用法不同群體有不同的說法。數據庫工作者通常說成***物理***日志(`physical logging`)和***邏輯***日志(`logical logging`)。物理日志是指記錄每一行被改變的內容。邏輯日志記錄的不是改變的行而是那些引起行的內容改變的`SQL`語句(`insert`、`update`和`delete`語句)。 分布式系統文獻通常把處理和復制(`processing and replication`)方案寬泛地分成兩種。『狀態機器模型』常常被稱為主-主模型(`active-active model`), 記錄輸入請求的日志,各個復本處理每個請求。 對這個模型做了細微的調整稱為『主備模型』(`primary-backup model`),即選出一個副本做為`leader`,讓`leader`按請求到達的順序處理請求,并輸出它請求處理的狀態變化日志。 其他的副本按照順序應用`leader`的狀態變化日志,保持和`leader`同步,并能夠在`leader`失敗的時候接替它成為`leader`。 [![](https://box.kancloud.cn/2015-08-28_55dfffda2705a.png)](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/images/active_and_passive_arch.png) 為了理解兩種方式的差異,我們來看一個不太嚴謹的例子。假定有一個要復制的『算法服務』,維護一個獨立的數字作為它的狀態(初始值為0),可以對這個值進行加法和乘法運算。 主-主方式所做的可能的是輸出所進行的變換的日志,比如『+1』、『*2』等。各個副本都會應用這些變換,從而經過一系列相同的值。 而主備方式會有一個獨立的`Master`執行這些變換并輸出結果日志,比如『1』、『3』、『6』等。 這個例子也清楚的展示了為什么說順序是保證各副本間一致性的關鍵:加法和乘法的順序的改變將會導致不同的結果。 [![](https://box.kancloud.cn/2015-08-28_55dfffdc3160c.jpg)](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/images/paxos_postcard.jpg) 分布式日志可以看作是建模[一致性](https://en.wikipedia.org/wiki/Consensus_(computer_science))(`consensus`)問題的數據結構。 因為日志代表了『下一個』追加值的一系列決策。 你需要瞇起眼睛才能從[`Paxos`](http://en.wikipedia.org/wiki/Paxos_(computer_science))算法簇中找到日志的身影,盡管構建日志是它們最常見的實際應用。?`Paxos`通過稱為`multi-paxos`的一個擴展協議來構建日志,把日志建模為一系列一致性值的問題,日志的每個記錄對應一個一致性值。 日志的身影在[`ZAB`](http://www.stanford.edu/class/cs347/reading/zab.pdf)、[`RAFT`](https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf)和[`Viewstamped Replication`](http://pmg.csail.mit.edu/papers/vr-revisited.pdf)等其它的協議中明顯得多,這些協議建模的問題直接就是維護分布式一致的日志。 個人有一點感覺,在這個問題上,我們的思路被歷史發展有些帶偏了,可能是由于過去的幾十年中,分布式計算的理論遠超過了其實際應用。 在現實中,一致性問題是有點被過于簡單化了。計算機系統幾乎不需要決定單個的值,要的是處理一序列的請求。 所以,日志而不是一個簡單的單值寄存器,是更自然的抽象。 此外,對算法的專注掩蓋了系統底層所需的日志抽象。 個人覺得,我們最終會更關注把日志作為一個商品化的基石而不是考慮它的實現,就像我們經常討論哈希表而不糾結于它的細節, 比如使用線性探測的雜音哈希(`the murmur hash with linear probing`)還是某個變種。 日志將成為一種大眾化的接口,可以有多種競爭的算法和實現,以提供最好的保證和最佳的性能。 ## [](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1-what-is-a-log.md#變更日志101表與事件的二象性duality)變更日志101:表與事件的二象性(`duality`) 讓我們繼續聊一下數據庫。變更日志 和 表之間有著迷人的二象性。 日志類似借貸清單和銀行處理流水,而數據庫表則是當前賬戶的余額。如果有變更日志,你就可以應用這些變更生成數據表并得到當前狀態。 表記錄的是每條數據的最后狀態(日志的一個特定時間點)。 可以認識到日志是更基本的數據結構:日志除了可用來創建原表,也可以用來創建各類衍生表。 (是的,表可以是非關系型用戶用的鍵值數據存儲(`keyed data store`)。) [![](https://box.kancloud.cn/2015-08-28_55dfffdeb80cc.jpg)](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/images/yin-yang.jpg) 這個過程也是可逆的:如果你對一張表進行更新,你可以記錄這些變更,并把所有更新的『變更日志(`changelog`)』發布到表的狀態信息中。 這些變更日志正是你所需要的支持準實時的復制。 基于此,你就可以清楚的理解表與事件的二象性: 表支持了靜態數據,而日志記錄了變更。日志的魅力就在于它是變更的*完整*記錄,它不僅僅包含了表的最終版本的內容, 而且可以用于重建任何存在過其它版本。事實上,日志可以看作是表***每個***歷史狀態的一系列備份。 這可能會讓你想到源代碼的版本控制(`source code version control`)。源碼控制和數據庫之間有著密切的關系。 版本管理解決了一個和分布式數據系統要解決的很類似的問題 —— 管理分布式的并發的狀態變更。 版本管理系統建模的是補丁序列(`the sequence of patches`),實際上這就是日志。 你可以檢出當前的代碼的一個『快照』并直接操作,這個代碼快照可以類比成表。 你會注意到,正如有狀態的分布式系統一樣,版本控制系統通過日志來完成復制:更新代碼即是拉下補丁并應用到你的當前快照中。 從銷售日志數據庫的公司[`Datomic`](http://www.datomic.com/)那里,大家可以看到一些這樣的想法。?[這個視頻](https://www.youtube.com/watch?v=Cym4TZwTCNU)比較好地介紹了他們如何在系統中應用這些想法。 當然這些想法不是只專屬于這個系統,這十多年他們貢獻了很多分布式系統和數據庫方面的文獻。 這節的內容可能有點理論化了。但別沮喪!后面馬上就是實操的干貨。 ## [](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1-what-is-a-log.md#接下來的內容)接下來的內容 本文剩下的內容,我會試著重點講述,除了作為分布式計算內部實現或模型抽象,日志有什么優點。包含: 1. *數據集成*(`Data Integration`) —— 讓組織中所有存儲和處理系統可以容易地訪問組織所有的數據。 2. *實時數據處理*?—— 計算生成的數據流。 3. *分布式系統設計*?—— 如何通過集中式日志的設計來簡化實際應用系統。 所有這些用法都是通過把日志用做單獨服務來實現的。 上面這些場景中,日志的好處都來自日志所能提供的簡單功能:生成持久化的可重放的歷史記錄。 令人意外的是,能讓多臺機器以確定性的方式(`deterministic manner`)按各自的速度重放歷史記錄的能力是這些問題的核心。
                  <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>

                              哎呀哎呀视频在线观看