標籤: 網頁設計公司

  • MapReduce 論文閱讀筆記

    MapReduce 論文閱讀筆記

    目錄

    • Abstract
    • Introduction
    • 2 Programming Model
      • 2.1 Example
      • 2.2 Types
      • 2.3 More Examples
    • 3 Implementation
      • 3.1 Execution Overview
      • 3.2 Master Data Structures
      • 3.3 Fault Tolerance
        • Worker Failure (工作節點故障)
        • Master Failure(主節點故障)
        • Semantics in the Presence of Failures(語義可能存在的故障)
      • 3.4 Locality
      • 3.5 Task Granularity
      • 3.6 Backup Tasks
    • 4 Refinements
      • 4.1 Partitioning Function
      • 4.2 Ordering Guarantees
      • 4.3 Combiner Function
      • 4.4 Input and Output Types
      • 4.5 Side-effects
      • 4.6 Skipping Bad Records
      • 4.7 Local Execution
      • 4.8 Status Information
      • 4.9 Counters
    • Others

    Abstract

    MapReduce :

    • programming model 編程模型
    • an associated implementation for processing and generating large data sets.

    用戶只需要指定 Map(Map函數將 key/value 類型的 pair 生成中間結果的 pair) 和 Reduce 函數(Reduce 函數將所有具有相同中間結果的值組合起來)即可。

    MapReduce 封裝隱藏了分佈式系統并行計算的細節:

    • 輸入數據的分割
    • 計劃將程序分配到一組計算機中
    • 處理機器故障
    • 管理集群內部的通信

    程序(in functional style)分佈式的運行在大型分佈式的集群上,而且具有很好的可伸縮性 scalable。

    Introduction

    過去這些年,Google一直在尋找方法來實現處理大量數據(抓取到的文件,web日誌等)的方法,通常數據量很大而且必須分散在數以千計的電腦上來進行運算。為了處理如何使計算相互關聯,分配數據以及處理故障的問題,往往編寫大量的複雜代碼掩蓋了他們,最初的簡單計算的初衷卻被忽略掉。

    為了解決這種複雜性,抽象出了一個簡單的計算模型放到一個庫中,這個庫隱藏了可能出現的問題:

    • 并行計算
    • 容錯
    • 數據分發
    • 負載均衡

    這個抽象受到了 Lisp 以及很多函數式編程語言中存在的原語 mapreduce 的啟發。

    大多數并行計算都包含兩個步驟:

    • map:將每個邏輯記錄變成 key/value 的中間形式方便計算
    • reduce:將所有具有相同 key 的值組合到一起來進行合適的處理

    我們使用一個函數式的編程模型(functional programming model)可以讓處理大型的并行計算和使用重新執行作為容錯的主要機制變得很簡單。

    這項工作的主要貢獻是:提供了一個簡單但是很強大的接口(interface)讓自動化的并行計算和大規模計算的分發成為可能,結合該接口的實現,可以在商用機的大型集群上實現高性能。

    Section2 :描述了基本的編程模型給出幾個例子

    Section3 :描述MapReduce 接口針對集群運算環境的實現

    Section4 :一些針對該模型的細微的改良

    Section5 :針對實現設計出一系列性能衡量方法

    Section6 :MapReduce 在 Google 中的使用,以及使用 MapReduce 來重寫生產環境的索引系統

    Section7 :相關以及未來的工作

    2 Programming Model

    input: a set of key/value pairs

    output: a set of key/value pairs

    MapReduce 的用戶將只會使用兩個函數 MapReduce

    Map:用戶編寫,將輸入的 pair 變成 k/v 的中間 pairs,然後 MapReduce 會把具有相同 key 的 pair 送給 Reduce 函數

    Reduce: 用戶編寫,接受中間結果 key 和 key 的一系列值。將這些值組合起來成為更少的 k/v;通常每個 Reduce 函數只輸出一個 或者 0 個值。中間結果太多無法全部放到內存中,可以通過迭代的方法來處理大量的 value

    2.1 Example

    設想一個需要統計文件中每個單詞數量的一個問題,我們很可能編寫這樣的代碼:

    map(String key, String value):
    	// key: document name
    	// value: document contents
    	for each word w in value:
    		EmitIntermediate(w, "1")
          
    reduce(String key, String values):
    	// key: a word
    	// values: a list of counts
    	int result = 0
      for each v in values
        result += ParseInt(v)
      Emit(AsString(result))
    

    map:給每個單詞添加一個屬性(出現的次數,這裏就是1)

    reduce:給每個特定的單詞加起來計算總數並且提交

    此外,用戶編寫代碼以使用輸入和輸出文件的名稱以及可選的調整參數來填充mapreduce規範對象。然後,用戶調用MapReduce函數,並將其傳遞給指定對象。用戶代碼與MapReduce庫(在C ++中實現)鏈接在一起。

    2.2 Types

    儘管前面偽代碼使用 string 來寫的輸入輸出,但是從概念上說,是由用戶來指定 map 和 reduce 的類型

    map (k1, v1)  ->  list(k2, v2)
    map (k2, list(v2)) -> list(v2)
    

    輸入值和中間值來自不同的域,中間值和輸出值來自相同的域

    C ++實現在用戶定義的函數之間來回傳遞字符串,並將其留給用戶代碼以在字符串和適當的類型之間進行轉換

    2.3 More Examples

    這有一些可以使用 MapReduce 簡化的計算:

    Distributed Grep: 分佈式的匹配,map 函數提交一個符合匹配的 line, reduce 的作用只是複製中間結果到輸出

    Count of URL Access Frequency: 網頁訪問計數,map 處理網頁請求並且輸出中間結果為 <URL, 1>, reduce 功能是將所有的相同的 URL 計算到一起提交為 <URL, total count>

    Reverse Web-Link Graph: 翻轉網絡鏈接圖, map 輸出 <target, source> pairs ,將 target 命名為 source。reduce函數連接與給定目標URL關聯的所有源URL的列表,並提交該對 <target, list(source)>

    Term-Vector per Host: 術語向量是出現在一篇文章中最重要的術語集合列表<word, frequency> pairs。map 函數給每個輸入文件輸出一個 <hostname, term vector> pairs,reduce 函數傳遞給特定主機的術語向量,然後去掉不常出現的向量最後提交一個 <hostname, term vector> pair

    Invert Index:map函數解析每個文檔,併發出一系列<單詞,文檔ID>對。 reduce函數接受給定單詞的所有對,對相應的文檔ID進行排序,併發出一個“單詞,列表(文檔ID)”對。setofall輸出對形成一個簡單的倒排索引。易於擴展此計算以跟蹤單詞位置。

    Distributed Sort: 分佈式排序,map函數功能從每個記錄中提取鍵,併發出一個<key, record>對。 reduce函數將所有對保持不變。這種計算取決於第4.1節中描述的分區功能和第4.2節中描述的排序屬性。

    3 Implementation

    MapReduce 可以有很多不同的實現,正確實現是根據你自己所在的環境來進行實現,例如某個實現可能很適合一個共享內存的小機器,某個實現可能是在NUMA多處理器的環境下,也可能是在一個大的網絡連接的集群的機器中。

    NUMA Non-uniform memory access

    非統一內存訪問架構是一種為多處理器的電腦設計的內存架構,內存訪問時間取決於內存相對於處理器的位置。在NUMA下,處理器訪問它自己的本地內存的速度比非本地內存快一些。 非統一內存訪問架構的特點是:被共享的內存物理上是分佈式的,所有這些內存的集合就是全局地址空間

    這節描述的是 Google 雲計算環境下廣泛使用的,下面是 Google 的配置:

    1. 機器,都是典型的Linux系統,運行在基於x86的雙處理器上,每台機器 2-4GB 內存
    2. 網絡,使用商品網絡硬件,在機器級別通常為100Mb/s或1Gb/s,但平均平均對分帶寬要小得多
    3. 集群中有上百或者上千個機器,所以機器故障出現很正常
    4. 存儲,使用廉價的 IDE 硬盤直接保存每個機器自己的數據,開發出的分佈式文件系統來管理這些磁盤上的文件。文件系統使用複製來在不可靠的硬件上提供可用性和可靠性。
    5. 用戶通過一個任務調度系統提交任務。每個工作包含一系列的任務,使用任務調度器來分配到集群中可用的機器上

    3.1 Execution Overview

    Map 調用分佈在多個機器上,自動將輸入數據分配成 M 組,輸入的分割可以并行的發生在不同的機器上。 Reduce 調用也是分佈式的,通過將中間值的key使用一個分割函數(例如:hash(key) mod R)來將任務分配到不同的機器上。分區數量 R 的取值和分區數量也是通過用戶來指定的。

    下面這個圖說明了 MapReduce 執行的完整流程:

    1. 用戶程序中的 MapReduce 庫首先將輸入文件分成 M 份(每份 16MB – 64 MB),然後開始在集群中複製很多拷貝
    2. 程序中有一份拷貝是特殊的(master)。剩下的 worker 來被分配工作,有 M 個map任務和 R 個 reduce 任務來分配給不同的 worker。master 來挑選空閑的 worker 分配給他們每個一個 map task 或者 reduce task
    3. 一個被分配到 map 工作的 worker 將會從對應的分割的內容中讀取。它會解析 k/v pair 到輸入數據並且傳給到用戶定義的 map 函數。Map 函數產生的中間 key/value 數據將會被保存在內存的緩存中
    4. 緩存中的 pair 會被周期性的寫入到本地磁盤上,通並且過分割函數將該文件分成的 R 個區域。這些緩衝對的位置在本地磁盤上被傳遞迴主服務器,該主服務器負責將這些位置轉發給reduce worker。
    5. 當一個 reduce worker 被 master 告知這些存儲的區域,reduce worker 將使用遠程過程調用來從 map workers 的本地磁盤以及緩存中讀取 pair 對。當一個 reduce worker 讀取了所有的中間數據,它將會跟配相同的 key 來進行排序。排序是必需的因為通常會有很多不同的 key 映射到同一個 reduce 任務。如果中間數據太大來放到內存中排序,外排序就會被使用
    6. reduce worker 迭代排過序的中間數據,對於每個獨特的中間值 key,它會傳遞這個 key 和對應中間值到用戶定義的 reduce 函數中來處理。Reduce函數的輸出將附加到此reduce分區的最終輸出文件中
    7. 當所有的 map task 和 reduce task 都被完成之後,master 喚醒用戶程序。這個時候,MapReduce 的調用返回到用戶的代碼邏輯中

    在成功的完成之後,mapreduce執行的輸出將會在 R 個輸出文件中(每個reduce task 都會被用戶指定文件的名稱)。通常來說,用戶不會將 R 個輸出文件合併成一個,而是將這個文件作為另一個 MapReduce 的輸入。或者把他們當成另外的分佈式程序的輸入

    3.2 Master Data Structures

    master 保存一些數據結構。對於每個 map 和 reduce 任務,它會保存狀態(idle,in-progress,completed),以及識別每個 worker machine(非空閑任務)。

    master 是處於 map 任務發送到 reduce 任務中間的導管,master 會保存中間文件區域的位置。因此,對於每個完成的 map 任務, master 保存 R 個由map任務產生的中間文件的大小和位置。當 map 任務完成之後,會更新這些文件的位置和大小。這些信息將逐漸被推送到已經在工作的 reduce 任務。

    3.3 Fault Tolerance

    由於 MapReduce 是用來在大量機器上處理大量數據的一個庫,所以這個庫必需能夠有很好的容錯能力。

    Worker Failure (工作節點故障)

    master 節點周期性的 ping 每個 worker 節點。如果在一個特定的時間內沒有收到回復,那麼 master 節點就會將這個 worker 標記為失敗。完成 map 任務的 worker 節點將會被重置為 idle 空閑狀態,然後就可以被其他 worker 節點安排。相似的,如果一個節點上的 map 或者 reduce 任務在執行過程中失敗了,那麼這個任務將會被重置然後分配然後重新分配。

    如果一個 map 任務的節點在完成任務之後出現故障,那麼就需要重新執行這個任務,因為這個節點變得不可訪問。但是如果是 reduce 任務完成之後節點出現故障,不需要重新執行,這是因為 reduce 任務的輸出被保存到一個全局文件系統中。

    當一個 map 任務首先在節點 A 上執行之後在節點 B 上執行時,所有正在執行的 reduce 節點將會被告知這次重新執行過程。所有還沒有從 worker A 讀取數據的 reduce 任務將會 worker B 讀取。

    MapReduce 可以處理大規模的 worker 節點故障。例如在一次 MapReduce 任務中,一個由80台計算機組成的集群由於網絡問題無法訪問,MapReduce 的 master 節點只是簡單的讓那些不能正常執行任務的工作節點再次執行任務,然後繼續向前執行任務直到完成 MapReduce 操作。

    Master Failure(主節點故障)

    讓 master 節點周期性的上述master節點的數據結構的檢查點。如果 master task 失敗了,可以從上一個檢查點的拷貝恢復。但是如果只有一個主節點,那麼出現故障的可能性非常小,因此如果主節點出現故障,我們的當前的實現就中止了此次 MapReduce 任務。客戶端可以檢查到這種情況,然後可以選擇是否重試 MapReduce 操作。

    Semantics in the Presence of Failures(語義可能存在的故障)

    當用戶指定的 map 和 reduce 操作對於他們的輸入輸出都確定好了之後,分佈式的實現將會產生一個類似於線性執行過程任務執行的結果。

    我們依賴於 map 和 reduce 任務的 原子性 commit 作為這個特性的保證。每個執行過程中的任務都會將把他的輸出保存到一個私有的臨時文件中。一個 reduce 任務產生一個這樣的文件,但是一個 map 任務將會產生 R 個這樣的文件。當一個 map 任務完成之後, worker 節點發送包含這 R 個文件名的消息到 master 節點。如果這個節點已經接收到完成的消息,那麼將會忽略這個消息,否則將會把這些文件名保存到 master 節點的數據結構中。

    當一個 reduce 任務完成的時候,reduce worker 將會原子性的將它的臨時文件重命名成一個輸出文件。如果有以個 reduce 任務在多個機器上同時完成,那麼這個重命名的操作將會對於一個輸出文件多次執行。我們依賴於基礎文件系統提供的原子重命名操作,以確保最終文件系統狀態僅包含一次執行reduce任務所產生的數據。

    map 和 reduce 操作絕大部分都是確定性的,事實上我們的語義將會和線性順序執行的程序的結果一致,這樣很容易分析程序的行為。當 map/reduce 操作是不確定的時候,我們提供弱化但是可信的語義。例如在一個不確定的語義中,一個特定 reduce 任務的輸出和這個任務順序執行的結果一致。然而,用於不同reduce任務R2的輸出可以對應於由不確定性程序的不同順序執行所產生的用於R2的輸出。(這裏保留疑問,沒有太懂什麼意思,指的是有可能是線性結果一致的意思嗎?)

    考慮有一個 map 任務 M,和兩個 reduce 任務 R1,R2,e(Ri)是 Ri提交的結果,弱一點的語義指的是,e(R1) 可能讀取的 M 的一個執行的結果而 e(R2) 可能讀取的是 R 執行輸出的另外一個結果。

    3.4 Locality

    網絡帶寬是在雲計算環境中比較稀缺的資源(盡量少用)。通過將輸入文件(由GFS保管)保存到本地磁盤上來減少網絡帶寬的使用。GFS 將每個文件分成 64 MB的塊,然後將每塊保存幾個副本(通常為3份)在不同的機器上。MapReduce 盡量將這些位置信息保存下來然後盡量將含有某個文件主機的任務分配給它,這樣就可以減少網絡的傳遞使用。如果失敗,那麼將會嘗試從靠近輸入數據的一個副本主機去啟動這個任務。當在一個集群上執行大型的 MapReduce 操作的時候,輸入數據一般都是本地讀取,減少網絡帶寬的使用。

    3.5 Task Granularity

    我們將一個 map 任務分成 M 塊,然後 reduce 會處理最後輸出成 R 塊。

    理想情況下,M 和 R 應該遠遠大於集群中的 worker 節點數量。讓每個節點執行不同的任務將會有利於動態的負載均衡,同時會加速當一個 worker 節點故障之後的恢復,map 任務完成之後可以分配到所有的其他節點上。

    R 和 M 在實現過程中會有邊界,因為 schedule 決策需要 O(M + R)的時間,保存這個信息到內存中需要 O(M*R)的複雜度(常數內存很小)。

    R 通常是由用戶指定的,這是由於每個 reduce 任務的輸出將會輸出到單獨的文件中。在實際中,通常 M 被選擇到每個單獨的任務輸入數據將會是 16MB ~ 64MB,讓 R 要比我們使用的機器的數目的小几倍。

    例如,M =20,000,R = 5,000,worker machines = 2000

    3.6 Backup Tasks

    讓整個 MapReduce 任務時間延長的原因主要有 “拖延者”:某一個機器在 map/reduce 任務上花費了太多的時間。導致這個 “拖延者” 的原因可能有很多,比如一塊讀寫速度超級慢的硬盤 1MB/s(其他的是 30MB/s)比如集群在這個機器上也分配了其他任務,這些任務競爭使用 CPU、硬盤網絡等等。我們最近遇到的一個問題是機器初始化代碼中的一個錯誤,該錯誤導致禁用了處理器緩存:受影響機器的計算速度降低了一百倍。

    4 Refinements

    儘管上面說的夠用了,但是我們還是找到一些可以優化的點。

    4.1 Partitioning Function

    用戶將會指定輸出文件的數量 R。輸入數據將會根據中間值來把這些數據分區。一個默認的分區函數就是 hash函數(hash(key) mod R) 。通常情況下這樣很好,但是在某些情況下不是很好。例如,輸出數據是 URL key,我們希望具有相同主機 hostname 的 URL 在一起,這樣,MapReduce 提供了用戶自己制定 分區函數的方式,例如可以寫為(hash(Hostname(urlkey))),這樣具有相同的 hostname 的URL將會在一個相同的輸出文件中。

    4.2 Ordering Guarantees

    我們保證了在某個給定的分區中,中間值的 k/v pair 將會按照增序排列,這樣在某些需要有序的場景下是很有用的。

    4.3 Combiner Function

    在某些情況下,最終的輸出文件reduce是需要根據中間值來合併的。例如在2.1的 word count 中,需要統計每個單詞的數目,我們輸出的是 <word, 1> 這樣的形式。這些pair都需要通過網絡來進行發送到 reduce 工作節點,我們提供了一個 combiner 函數,讓用戶可以在發送數據之前執行的函數,也就是說在本地先合併,然後再發送到網絡中去。

    在每個執行 map task 的機器都會執行 conbine 函數。

    combine 和 reduce 的唯一區別:

    • combine 輸出是到中間值文件中
    • reduce 輸出到一個最終的輸出文件中

    4.4 Input and Output Types

    MapReduce 庫提供了幾種輸入的類型。

    例如,在 “text” 模式下輸入將每一個行當作 k/v pair,這行的偏移量當作 key,這行的內容當作 value。

    用戶可以通過實現 reader 接口在實現自己的輸入類型,儘管大多數用戶都只使用預定義的類型。

    reader 不一定要從文件中讀取數據,也可以從數據庫中讀取數據,或者從內存中的某個的某個數據結構中獲取數據。

    同樣的,輸出也可以自定義。

    4.5 Side-effects

    在某些情況下,用戶需要產生一些額外的輸出文件在reduce 的輸出結果中。我們依靠這個應用程序自己的編寫者來使此類副作用成為原子和冪等的。通常應用程序將會寫入一個臨時文件中,然後當它完成的時候將會原子性的重命名這個文件。

    我們不提供原子性的兩節點提交由一個任務產生的多個輸出文件。因此,產生多個輸出的結果的任務應該是確定性的。

    4.6 Skipping Bad Records

    在處理大量數據的時候,由於用戶的 map/reduce 函數的錯誤在處理某些數據的時候產生bug,這個時候可以選擇跳過這些 bug。有的時候我們可以查找到bug所在的地方,但是有的時候我們找不到bug,因為可能是第三方的庫導致的錯誤,我們提供了一種可選的執行模式來跳過這些可能出現錯誤的記錄。

    每個 worker 進程都會有一個監聽段錯誤和總線錯誤的處理器。在執行用戶的 map/reduce 函數之前,mapreduce 將會在一個全局變量中保存順序編號。如果用戶代碼產生了一個 signal,那麼就會發送一個 UDP包到 MapReduce 的 master 節點上。當 master 節點發現在某個幾點上出現了很多次故障的時候,之後就會跳過這個記錄。

    4.7 Local Execution

    在 Map/Reduce 中debug需要一些 trick,因為在分佈式系統中執行可能是在幾千台機器中,工作分配也是動態的。MapReduce 提供了一個另外的本地MapReduce 的本地實現(順序執行),這樣就可以在本地來進行 debug了。

    4.8 Status Information

    master 節點通過 HTTP 服務器提供一個显示當前狀態的網頁。這個界面显示了多少任務完成了,多少任務還在執行,中間數據有多少字節等,還包含了錯誤的標準輸出文件的鏈接等,用戶可以通過這個界面預估還有多久可以完成任務。當執行很慢的時候,可以通過這個界面來查找原因。

    另外,top-level 的狀態信息還會显示哪些 worker 節點有故障,哪些任務失敗了。

    4.9 Counters

    提供一個全局的計數器來統計某些數據,例如統計大寫單詞的出現次數。

     Counter* uppercase;
      uppercase = GetCounter("uppercase");
      map(String name, String contents):
        for each word w in contents:
    			if (IsCapitalized(w)): 
    				uppercase->Increment(); 
    			EmitIntermediate(w, "1");
    

    計數器的值會從每個節點周期性的發送到master節點,主節點統計計數器的值並且在 狀態頁面显示。

    有些值MapReduce 會自己去統計。

    計數器功能對於完整性檢查MapReduce操作的行為很有用。例如,在某些MapReduce操作中,用戶代碼可能想要確保所生成的輸出對的數量完全等於所處理的輸入對的數量,或者所處理的德語文檔的比例在該比例之內。

    Others

    shuffle:將所有具有相同 key 的value 發送個單個的 reduce 進程,在網絡上傳輸數據,是MapReduce代價最大的部分

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※想知道最厲害的網頁設計公司"嚨底家"!

    ※幫你省時又省力,新北清潔一流服務好口碑

    ※別再煩惱如何寫文案,掌握八大原則!

  • .NET Core請求控制器Action方法正確匹配,但為何404?

    .NET Core請求控制器Action方法正確匹配,但為何404?

    前言

    有些時候我們會發現方法名稱都正確匹配,但就是找不到對應請求接口,所以本文我們來深入了解下何時會出現接口請求404的情況。

    匹配控制器Action方法(404)

    首先我們創建一個web api應用程序,我們給出如下示例控制器代碼

    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherController : ControllerBase
    {
        [HttpGet]
        string Get()
        {
            return "Hello World";
        }
    }

     

    當我們進行如上請求時會發現接口請求不到,這是為何呢?細心的你應該可能發現了,對於請求方法是私有,而不是公共的,當我們加上public就可以請求到了接口

    [HttpGet("get")]
    public string Get()
    {
        return "Hello World";
    }

    匹配控制器Action方法本質

    經過如上示例,那麼對於Action方法的到底要滿足怎樣的定義才能夠不至於請求不到呢?接下來我們看看源碼怎麼講。我們找到DefaultApplicationModelProvider類,在此類中有一個OnProvidersExecuting方法用來構建控制器和Action方法模型,當我們構建完畢所有滿足條件的控制器模型后,緊接着勢必會遍歷控制器模型去獲取對應控制器模型下的Action方法,這裏只截取獲取Action方法片段,源碼如下:

    foreach (var controllerType in context.ControllerTypes)
    {    
        //獲取控制器模型下的Action方法
        foreach (var methodInfo in controllerType.AsType().GetMethods())
        {
            var actionModel = CreateActionModel(controllerType, methodInfo);
            if (actionModel == null)
            {
                continue;
            }
    
            actionModel.Controller = controllerModel;
            controllerModel.Actions.Add(actionModel);    
        }
    }

    上述紅色標記則是創建Action模型的重點,我們繼續往下看到底滿足哪些條件才創建Action模型呢?

    protected virtual ActionModel CreateActionModel(TypeInfo typeInfo, MethodInfo methodInfo)
    {
        if (typeInfo == null)
        {
            throw new ArgumentNullException(nameof(typeInfo));
        }
    
        if (methodInfo == null)
        {
            throw new ArgumentNullException(nameof(methodInfo));
        }
    
        if (!IsAction(typeInfo, methodInfo))
        {
            return null;
        }    
        ......    
    }

    到了這個方法裏面,我們找到了如何確定一個方法為Action方法的源頭,由於該方法有點長,這裏我採用文字敘述來作為判斷邏輯,如下:

    protected virtual bool IsAction(TypeInfo typeInfo, MethodInfo methodInfo)
    {
        //如果有屬性訪問器(無效)
    
        //如果有NonAction特性標識無效)
    
        //如果重寫Equals(Object), GetHashCode()方法(無效)
    
        //如果實現Dispose方法(無效)
    
        //如果是靜態方法(無效)
    
        //如果是抽象方法(無效)
    
        //如果是構造函數(無效)
    
        //如果是泛型方法(無效)
    
        //必須為公共方法
        return methodInfo.IsPublic;
    }

    如上是從方法定義的角度來過濾而獲取Action方法,除此之外,我們請求方法的名稱還可以自定義,比如通過路由、ActionName特性指定,那麼這二者是否存在優先級呢?比如如下示例:

    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherController : ControllerBase
    {
        [HttpGet]
        [ActionName("get1")]
        public string get()
        {
            var routeValue = HttpContext.Request.RouteValues.FirstOrDefault();
    
            return routeValue.Value.ToString();
        }
    }

    我們可以看到此時將以ActionName特性作為方法名稱。所以在上述過濾方法定義后開始構建方法模型,在此之後還會再做一步操作,那就是查找該方法是否通過ActionName特性標識,若存在則以ActionName特性標識給定的名稱作為請求方法名稱,否則以方法定義名稱為準,源碼如下:

    var actionModel = new ActionModel(methodInfo, attributes);
    
    AddRange(actionModel.Filters, attributes.OfType<IFilterMetadata>());
    
    var actionName = attributes.OfType<ActionNameAttribute>().FirstOrDefault();
    if (actionName?.Name != null)
    {
        actionModel.ActionName = actionName.Name;
    }
    else
    {
        actionModel.ActionName = methodInfo.Name;
    }

    還沒完,若是將路由特性放到Action方法上,如下,此時請求接口應該是weather/get還是weather/get1呢?

    [ApiController]
    public class WeatherController : ControllerBase
    {
        [HttpGet]
        [Route("weather/get")]
        [ActionName("get1")]
        public string get()
        {
            var routeValue = HttpContext.Request.RouteValues.FirstOrDefault();
    
            return routeValue.Value.ToString();
        }
    }

    此時若我們以weather/get1請求將出現404,還是以路由特性模板給定為準進行請求,但最終會將路由上Action方法名稱通過ActionName特性上的名稱賦值給Action模型中的ActionName進行覆蓋,源碼如下,所以上述我們得到的action名稱為get1,,當然這麼做沒有任何實際意義。

    public static void AddRouteValues(ControllerActionDescriptor actionDescriptor,ControllerModel controller,ActionModel action)
    {
        foreach (var kvp in action.RouteValues)
        {
            if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key))
            {
                actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value);
            }
        }
    
        if (!actionDescriptor.RouteValues.ContainsKey("action"))
        {
            actionDescriptor.RouteValues.Add("action", action.ActionName ?? string.Empty);
        }
    
        if (!actionDescriptor.RouteValues.ContainsKey("controller"))
        {
            actionDescriptor.RouteValues.Add("controller", controller.ControllerName);
        }
    }

    總結

    本文我們只是單獨針對查找Action方法名稱匹配問題做了進一步的探討,根據源碼分析,對Action方法名稱指定會做3步操作:第一,根據方法定義進行過濾篩選,第二,若方法通過AcionName特性標識則以其所給名稱為準,否則以方法名稱為準,最終賦值給ActionModel上的ActionName屬性,第三,將ActionModel上的ActionName值賦值給路由集合中的鍵Action。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※教你寫出一流的銷售文案?

  • BMW 高階電動車 i3 與 i8 正式登陸

    BMW Corp  21 日首度針對中國大陸消費者行銷純電動車「i3 」,讓當地剛剛萌芽的高階電動車市場競爭開始升級。   華爾街日報 22 日報導,i3 21 日在大陸正式開賣、定價約 73,000 美元。i3 是 BMW 在大陸第一款純電動車,電動車製造商特斯拉 (Tesla) 才剛在 4 月份將大陸第一台「Model S」電動車交給當地顧客。Model S 在大陸的定價約 121,000 美元。   BMW 雖然並未透露正式的銷售目標,但該公司中國分部執行長 Karsten Engel 曾在 4 月表示,BMW 希望 2014 年能在當地賣出 1,000 台左右的 i3 與 i8。BMW 目前已經在北京、上海、深圳以及瀋陽指定了 7 家經銷商。   特斯拉成長動能逐漸趨緩,得在亞洲(尤其是大陸)加把勁,才能達成 2014 年預設的銷售目標。現在 BMW 又來搶食大餅,特斯拉可得趕緊擬定對策了。  

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※為什麼 USB CONNECTOR 是電子產業重要的元件?

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※台北網頁設計公司全省服務真心推薦

    ※想知道最厲害的網頁設計公司"嚨底家"!

    新北清潔公司,居家、辦公、裝潢細清專業服務

    ※推薦評價好的iphone維修中心

  • 高盛:再下60億美元資本 特斯拉就能顛覆汽車界

    上周,高盛分析師派翠克•阿爾尚博(Patrick Archambault)指出,特斯拉或許需要再投入60億美元現金(尤其在2017年至2025年之間),才能實現“到2020年電動汽車的年產量達到50萬輛”的目標,從而顛覆汽車市場。   而特斯拉希望在明年年底前交付10萬輛電動汽車,其中包括Model S和即將推出的Model X。阿爾尚博預測,特斯拉要實現既定目標,到2025年為止將需要生產180萬至320萬輛電動汽車。但是,屆時如果特斯拉未能實現這些生產目標,電池工廠所生產的多餘電池將可能最終由太陽能公司SolarCity所消化。   特斯拉已經為SolarCity生產了少量的蓄電元件,超級電池工廠竣工後將滿足SolarCity部分或全部的耗電需求。馬斯克表示,兩家公司能以獨特的方式相互相容。如果更多的美國人能接受太陽能用於住宅和商業供電,特斯拉及其電池製造合作夥伴松下就能把超級電池工廠過剩產能所餘下的蓄電元件提供給SolarCity。超級電池工廠每年將為特斯拉生產50萬件電池組,因此,特斯拉不打算成為SolarCity蓄電組件的主要供應商。但如果特斯拉達不到生產目標,超級電池工廠就可能為SolarCity多出出力。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

  • F-貿聯營收隨 Tesla 出貨倍增 2015 年可望翻倍成長

    從 2005 年開始就與美國電動車大廠 Tesla 合作,而貿聯的營收比重也隨著 Tesla 成長,從 2013 年的 3~5%,到 2014 年倍增到 8% 至 10%,有機會晉升貿聯的前五大客戶。   據了解,2013 年同期貿聯打入 Tesla 的零件料號總數約 45 個,目前已倍增到 100 個,法人推估,平均貿聯交貨每台電動車用線的成本可達 300~400 美元,以 2015 年 Tesla 出貨量上看 10  萬輛來看,2015 年對貿聯的營收貢獻可望維持近倍成長,營收占比拉高至 15~20%。  

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

  • 重歐美輕亞洲 特斯拉第200個充電站投入使用

    近日,特斯拉宣佈其第200個超級充電站已開放使用。這個超級充電站位於美國加州南部的奧克斯納德河流公園公務中心附近。特斯拉目前有57%的充電站位於美國。這些超級充電站可讓特斯拉電動汽車30分鐘充滿電。   特斯拉正不斷完善其充電網路,其向南有霍索恩(Hawthorne)和特甬牧場(Tejon Ranch)超級充電站,向北有索爾萬(Solvang)超級充電站,東部則有巴斯托(Barstow)超級充電站。他們表示明年其充電站網路將覆蓋美國98%的區域。   目前特斯拉已分別在北美、歐洲和亞洲建造了114座、66座、20座超級充電站。為了完善充電網路,特斯拉未來將在北美進一步縮小超級充電站間的間隙,並且將其將延伸至加拿大,而在歐洲,特斯拉將增大超級充電站密度和覆蓋國家。但是在亞洲,特斯拉的超級充電站建造計畫則顯得相對保守,如今在中國僅有7座。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    南投搬家公司費用需注意的眉眉角角,別等搬了再說!

    新北清潔公司,居家、辦公、裝潢細清專業服務

    ※教你寫出一流的銷售文案?

  • Tesla 第二產線將完工 預估產能跳增 3 倍

    近 3 個月前,特斯拉一度為了建置第 2 條產線而短暫停工,現在有分析師指出,擴廠工程已接近完成,且推估新產線產能還將跳增逾 3 倍。   Global Equities Research 分析師 Trip Chowdhry 最近參訪完特斯拉廠房後指出,新產線運轉已沒有問題,預估每週可產出 3,000 輛電動車。   特斯拉曾在第二季財報上揭露,原有產線每週產能約 800 輛,Chowdhry 預測約莫再 4 至 6 週的時間,舊產線產出即可提升至 1,000 輛。另外,Chowdhry 還注意到工廠內仍有許多閒置空間,似乎是預留給特斯拉正在開發的新一代平價電動車 Model 3。   廠房設施重整約花了特斯拉 1 億美元,若不算超級電池工廠,這是該公司史上最大單筆投資計畫。第 2 條產線開始投產後,特斯拉將可以 2 條產線同時生產 Model S 轎車與 Model X 運動休旅車。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※想知道最厲害的網頁設計公司"嚨底家"!

    ※幫你省時又省力,新北清潔一流服務好口碑

    ※別再煩惱如何寫文案,掌握八大原則!

  • 衣索比亞總理阿邁德推動環保、性平獲2019年諾貝爾和平獎

    貝爾和平獎11日出爐,得獎者是衣索比亞總理阿邁德(Abiy Ahmed),原因是他結束該國與鄰國厄利垂亞之間長達20年的戰火,這項創舉又激發了非洲地區一系列的外交突破,阿邁德也提倡性別平等、環境保護。

    阿邁德2018年4月上任,是該國第1位奧羅莫元首,在最初幾個月,他果斷、大膽地釋放政治犯,並對他們受到的酷刑予以譴責,也釋放被監禁的記者,甚至與政治反對派、民間社會對談,討論改革問題,並邀請先前流亡的政黨人士返國,還針對安全、司法部門進行重大改革。

    阿邁德也致力於性別、環保問題,例如在國境內植樹造林以遏制氣候變化的負面影響。

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是  USB CONNECTOR   ?

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※教你寫出一流的銷售文案 ?

  • BERT的前世今生

    BERT的前世今生

    Transformer

    Transformer來自論文: All Attention Is You Need

    別人的總結資源:

    1. 谷歌官方AI博客: Transformer: A Novel Neural Network Architecture for Language Understanding
    2. Attention機制詳解(二)——Self-Attention與Transformer谷歌軟件工程師
    3. 放棄幻想,全面擁抱Transformer:自然語言處理三大特徵抽取器(CNN/RNN/TF)比較中科院軟件所 · 自然語言處理 /搜索 10年工作經驗的博士(阿里,微博);
    4. Calvo的博客:Dissecting BERT Part 1: The Encoder,儘管說是解析Bert,但是因為Bert的Encoder就是Transformer,所以其實它是在解析Transformer,裏面舉的例子很好;
    5. 再然後可以進階一下,參考哈佛大學NLP研究組寫的“The Annotated Transformer. ”,代碼原理雙管齊下,講得也很清楚。
    6. 《Attention is All You Need》淺讀(簡介+代碼)這個總結的角度也很棒。

    A High-Level Look

    可以將輸入的語言序列轉換成另外一種序列,比如下圖的神經機器翻譯:

    Transformer模型由編碼器-解碼器組合組成,解碼器負責對序列進行編碼,提取時間和空間信息,解碼器負責利用時間和空間特徵信息進行上下文預測,下圖是單個結構:

    編碼器和解碼器堆棧的組合結構,在谷歌的實驗結構中採用了6個編碼器和6解碼器相對應,使模型的編碼能力和解碼能力達到一個平衡狀態(堆棧式結構):

    編碼器-解碼器的內部結構,類似seq2seq模型:

    seq2seq模型:

    Encoder: 由6個相同的層組成, 每層包含兩個sub-layers.第一個sub-layer就是multi-head attention layer,然後是一個簡單的全連接層。其中每個sub-layer都加了residual connection(殘差連接)和normalisation(歸一化)。

    Decoder: 由6個相同的層組成,這裏的layer包含三個sub-layers, 第一個sub-layer 是masked multi-head attention layer。這裡有個特別點就是masked, 作用就是防止在訓練的時候,使用未來的輸出的單詞。比如訓練時,第一個單詞是不能參考第二個單詞的生成結果的。Masked是在點乘attention操作中加了一個mask的操作,這個操作是保證softmax操作之後不會將非法的values連到attention中,提高泛化性。

    Self-Attention at a High Level

    假設下面的句子就是我們需要翻譯的輸入句:

    ”The animal didn’t cross the street because it was too tired”

    當模型處理單詞的時候,self attention層可以通過當前單詞去查看其輸入序列中的其他單詞,以此來尋找編碼這個單詞更好的線索。

    Self-Attention in Detail

    第一步是將輸入的嵌入詞向量通過三個不同的參數矩陣得到三個向量,分別是一個Query向量,一個Key向量和一個Value向量,參數矩陣分別為Wq,Wk,Wv,,如下圖所示:

    第二步是通過當前詞的q向量與其他詞的k向量計算當前詞相對於其他詞的得分,分數採用點積進行計算,如下圖所示:

    第三步和第四步是講得到的分數除以k值維數的平方根(k值維數為64,可以使訓練過程有更加穩定的梯度,這個歸一化的值是經驗所得),再通過softmax得到每個得分的標準化得分:

    第五步是對當前詞所得到的標準化值對所有value向量進行加權求和得到當前詞的attention向量,這樣就使不同單詞的嵌入向量有了attention的參与,從而預測上下文句子的時候體現不同的重要的重要程度。

    Matrix Calculation of Self-Attention

    • Attendtion向量計算的矩陣形式,通過全職矩陣進行詞向量的計算大大加快了神經網絡的速度

    • X矩陣中的每一行對應於輸入句子中的一個單詞。(圖中的4個方框論文中為512個)和q / k / v向量(圖中的3個方框論文中為64個)

    公式中濃縮前面步驟2到5來計算self attention層的輸出。

    The Beast With Many Heads

    使用“Multi-headed”的機制來進一步完善self-attention層。“Multi-headed”主要通過兩個方面改善了Attention層的性能,參數組成和子空間映射:

    Many Heads的優缺點:

    • 它拓展了模型關注不同位置的能力。Multi head 的每個參數矩陣都會記錄單詞的位置信息,使原來的單個位置信息變得更加複雜。

    • 它為attention層提供了多個“representation subspaces”。由下圖可以看到,在self attention中,我們有多個個Query / Key / Value權重矩陣(Transformer使用8個attention heads),使特徵的提取變得更加複雜,而不是作為一個整體的特徵進行,每個單獨的子空間都會進行上下文的信息融合

    在8個不同的子空間進行self-attention的操作,每個單詞生成獨立的8個向量

    將8個子空間生成的向量壓縮成一個大向量,每個向量的子空間矩陣能夠學習到更多細節,壓縮過程採用一個更大的參數矩陣進行,對multi-head向量進行組合,生成最終的特徵向量。

    整體的框圖來表示一下計算的過程:

    Representing The Order of The Sequence Using Positional Encoding

    其實上面介紹的網絡裏面並沒有考慮序列的位置信息,在RNN中不同時刻的信息是通過遞歸網絡的時間t來刻畫的,有明顯的時間刻度,所以引入了位置向量來解決時間刻度問題。

    為了讓模型捕捉到單詞的順序信息,添加位置編碼向量信息(POSITIONAL ENCODING),位置編碼向量不需要訓練,它有一個規則的產生方式,生成與詞嵌入向量有着相同的向量就可以。

    通過構造函數sin、cos來對位置進行嵌入,pos為單詞位置信息,而i用來表達dimension 這裏為了好說明,如果2i= dmodel, PE 的函數就是sin(pos/10000)。這樣的sin, cos的函數是可以通過線性關係互相表達的,通過兩個函數對奇偶維度進行編碼。位置編碼的公式如下圖所示:

    個人認為選擇正餘弦函數主要是在-1和1之間是一個對稱關係,兩個相鄰的維度編碼相差比較大,在位置上有更好的區分性,1000是序列的長度,一般盡量將取值範圍控制在四分一個周期裏面,這樣會使每一個序列的每一個維度都取唯一的值。

    The Residuals

    編碼器和解碼器裏面的每一層都採用殘差的思想進行訓練,目的就是為了解決網絡過深情況下的難訓練問題,殘差連接可以將目標值問題轉化成零值問題,一定程度也可以減少網絡的過擬合問題。

    使用殘差連接的編碼器內部結構:

    使用殘差連接的編碼器-解碼器內部結構:

    The Decoder Side

    通過自回歸方式進行預測,解碼器每一個時間步輸入一個單詞,然後輸出一個單詞,將預測的單詞作為下一時刻的輸入進行單詞的預測,直到預測結束。

    The Final Linear and Softmax Layer

    • 線性層是一個簡單的全連接神經網絡,模型一次生成一個輸出,我們可以假設模型從該概率分佈中選擇具有最高概率的單詞並丟棄其餘的單詞。

    • 對於最終句子的生成有2個方法:一個是貪婪算法(greedy decoding),一個是波束搜索(beam search)。

    Bidirectional Encoder Representation from Transformers

    Word Embedding

    • 線性模型,主要是對高維空間進行映射,其實是對one-hot向量的空間轉換。

    • 通過神經網絡對輸入的詞進行映射,獲取詞向量,一般有cbow和skip-gram兩種方法,此方法訓練的詞向量與上下文無關,並沒有參考位置信息,只是對詞的有無進行參考,採用的是負採樣,預測的時候進行的是一個二分類器,模型認為只要在下文中找出正確的詞就認為是完成了任務。

    尚未解決一詞多義等問題。比如多義詞Bank,有兩個常用含義,但是Word Embedding在對bank這個單詞進行編碼的時候,是區分不開這兩個含義的,因為它們儘管上下文環境中出現的單詞不同,但是在用語言模型訓練的時候,不論什麼上下文的句子經過word2vec,都是預測相同的單詞bank,而同一個單詞占的是同一行的參數空間,這導致兩種不同的上下文信息都會編碼到相同的word embedding空間里去。所以word embedding無法區分多義詞的不同語義,這就是它的一個比較嚴重的問題。

    Embedding from Language Models(ELMO)

    • ElMO採用雙向的LSTM做上下文相關的任務,從前到后和後到前分別做一遍LSTM的encoding操作,從而獲得兩個方向的token聯繫。

    • Word Embedding本質上是個靜態的方式,所謂靜態指的是訓練好之後每個單詞的表達就固定住了,以後使用的時候,不論新句子上下文單詞是什麼,這個單詞的Word Embedding不會跟着上下文場景的變化而改變,所以對於比如Bank這個詞,它事先學好的Word Embedding中混合了幾種語義 ,在應用中來了個新句子,即使從上下文中(比如句子包含money等詞)明顯可以看出它代表的是“銀行”的含義,但是對應的Word Embedding內容也不會變,它還是混合了多種語義。

    ELMO的本質思想是:

    事先用語言模型學好一個單詞的Word Embedding,此時多義詞無法區分,不過這沒關係。在我實際使用Word Embedding的時候,單詞已經具備了特定的上下文了,這個時候我可以根據上下文單詞的語義去調整單詞的Word Embedding表示,這樣經過調整后的Word Embedding更能表達在這個上下文中的具體含義,自然也就解決了多義詞的問題了。所以ELMO本身是個根據當前上下文對Word Embedding動態調整的思路。

    一樣的,在具體進行下游任務的時候,採用神經網絡參數微調的方法根據不同的詞的上下文環境對詞向量進行調整,從而得到同一詞的不同向量表示。

    缺點:

    • LSTM的抽取能力遠遠落後於Transformer,主要是并行計算能力

    • 拼接方式融合雙向特徵能力偏弱

    Bidirectional Encoder Representation from Transformers

    BRET採用兩階段模型,首先是語言模型預訓練;其次是使用Fine-Tuning模式解決下游任務。在預訓練階段採用了類似ELMO的雙向語言模型,雙向指的是對於預測單詞的上文和下文是否參与,如果都參与預測那麼就是雙向,雙向容易導致自己看自己的問題,後面提出mask來解決

    經過預訓練的BRET模型,其已經具備了豐富的詞向量特徵信息,然後將此詞向量信息與下游任務進行組合進行NLP下游任務,例如文本生成,文本分類。

    如何能夠更好將BRET模型與下游任務進行改造是一個比較複雜的問題,再好的預訓練語言模型都要與下游的任務模型相結合才有好的效果, BRET的優勢在於可以自由根據預訓練模型進行單詞級別的任務和句子級的任務。

    BRET模型的創新

    就是論文中指出的Masked 語言模型和Next Sentence Prediction。而Masked語言模型上面講了,本質思想其實是CBOW,但是細節方面有改進。

    Masked 語言模型:

    • 而Masked語言模型上面講了,本質思想其實是CBOW,但是細節方面有改進,掩蓋的同時,要輸出掩蓋的詞的位置,然後用真實詞來預測。
    • Mask LM主要是為了增加模型的魯棒性和實際性能,但是在訓練時使用mask過多會影響實際任務的表現,所以做了一些處理:隨機選擇語料中15%的單詞,把它摳掉,也就是用[Mask]掩碼代替原始單詞,然後要求模型去正確預測被摳掉的單詞。但是這裡有個問題:訓練過程大量看到[mask]標記,但是真正後面用的時候是不會有這個標記的,這會引導模型認為輸出是針對[mask]這個標記的,但是實際使用又見不到這個標記,這自然會有問題。為了避免這個問題, BRET改造了一下,15%的被選中要執行[mask]替身這項光榮任務的單詞中,只有80%真正被替換成[mask]標記,10%被狸貓換太子隨機替換成另外一個單詞,10%情況這個單詞還待在原地不做改動。這就是Masked雙向語音模型的具體做法。

    Next Sentence Prediction:

    • 指的是做語言模型預訓練的時候,分兩種情況選擇兩個句子,一種是選擇語料中真正順序相連的兩個句子;另外一種是第二個句子從語料庫中拋色子,隨機選擇一個拼到第一個句子後面。
    • 我們要求模型除了做上述的Masked語言模型任務外,附帶再做個句子關係預測,判斷第二個句子是不是真的是第一個句子的後續句子。之所以這麼做,是考慮到很多NLP任務是句子關係判斷任務,單詞預測粒度的訓練到不了句子關係這個層級,增加這個任務有助於下游句子關係判斷任務。所以可以看到,它的預訓練是個多任務過程。這也是BRET的一個創新,一般用於句級任務。

    Transformer&BERT總結

    • 首先是兩階段模型,第一階段雙向語言模型預訓練,這裏注意要用雙向而不是單向,第二階段採用具體任務Fine-tuning或者做特徵集成;

    • 第二是特徵抽取要用Transformer作為特徵提取器而不是RNN或者CNN;

    • 第三,雙向語言模型可以採取CBOW的方法去做(當然我覺得這個是個細節問題,不算太關鍵,前兩個因素比較關鍵)。 BRET最大的亮點在於效果好及普適性強,幾乎所有NLP任務都可以套用BRET這種兩階段解決思路,而且效果應該會有明顯提升。可以預見的是,未來一段時間在NLP應用領域,Transformer將佔據主導地位,而且這種兩階段預訓練方法也會主導各種應用。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※為什麼 USB CONNECTOR 是電子產業重要的元件?

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※台北網頁設計公司全省服務真心推薦

    ※想知道最厲害的網頁設計公司"嚨底家"!

    新北清潔公司,居家、辦公、裝潢細清專業服務

    ※推薦評價好的iphone維修中心

  • Docker(三)Docker常用命令

    Docker(三)Docker常用命令

    Docker常用命令

    幫助命令

    # 显示 Docker 版本信息
    docker version  
    
    # 显示系統信息,包括鏡像和容器的數量
    docker info 
    
    # 查看幫助文檔 幫助文檔地址:https://docs.docker.com/reference/
    docker [命令] --help  
    

    鏡像命令

    查看最近創建的鏡像

    docker images 查看最近創建的鏡像

    docker images [OPTIONS] [REPOSITORY[:TAG]]
    
    # 幫助文檔
    [root@hwh1 ~]# docker images --help 
    Usage:	docker images [OPTIONS] [REPOSITORY[:TAG]]
    List images
    Options:
      -a, --all             Show all images (default hides intermediate images)    显示所有鏡像
          --digests         Show digests                                           显示摘要
      -f, --filter filter   Filter output based on conditions provided             根據提供的條件過濾輸出
          --format string   Pretty-print images using a Go template                用 Go 模板打印出一個圖像
          --no-trunc        Don't truncate output                                  不截斷輸出
      -q, --quiet           Only show numeric IDs                                  只显示数字 ID
    
    # 查看最近創建的鏡像
    # REPOSITORY  鏡像的倉庫源
    # TAG  鏡像的標籤
    # IMAGE ID  鏡像的id
    # CREATED  鏡像的創建時間
    # SIZE  鏡像的大小
    [root@hwh1 ~]# docker images   
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hello-world         latest              bf756fb1ae65        5 months ago        13.3kB
    
    # 查看所有鏡像
    [root@hwh1 ~]# docker images -a
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hello-world         latest              bf756fb1ae65        5 months ago        13.3kB
    
    # 只显示数字 ID
    [root@hwh1 ~]# docker images -q
    bf756fb1ae65
    

    搜索鏡像

    docker search 搜索鏡像

    docker search [OPTIONS] TERM
    
    [root@hwh1 ~]# docker search --help 
    Usage:	docker search [OPTIONS] TERM
    Search the Docker Hub for images
    Options:
      -f, --filter filter   Filter output based on conditions provided   根據提供的條件過濾輸出
          --format string   Pretty-print search using a Go template      用 Go 模板打印出一個圖像
          --limit int       Max number of search results (default 25)    搜索結果的最大值限制
          --no-trunc        Don't truncate output                       不截斷輸出
    
    
    [root@hwh1 ~]# docker search mysql
    NAME                              DESCRIPTION                                     STARS    OFFICIAL            AUTOMATED
    mysql                             MySQL is a widely used, open-source relation…   9626
    

    下載鏡像

    docker pull 下載鏡像

    docker pull [OPTIONS] NAME[:TAG|@DIGEST]
    
    [root@hwh1 ~]# docker pull --help 
    Usage:	docker pull [OPTIONS] NAME[:TAG|@DIGEST]
    Pull an image or a repository from a registry
    Options:
      -a, --all-tags                Download all tagged images in the repository      下載倉庫中標記所有的鏡像,拿來選擇版本
          --disable-content-trust   Skip image verification (default true)            跳過圖像驗證       
          --platform string         Set platform if server is multi-platform capable  如果服務器支持多平台,則設置平台
     -q, --quiet                   Suppress verbose output                           禁止詳細輸出              
    
    # 下載鏡像
    [root@hwh1 ~]# docker pull mysql
    Using default tag: latest                     # 版本信息(默認不設置tag,則為最新版)
    latest: Pulling from library/mysql           
    8559a31e96f4: Pull complete                   # 分層下載,docker image 的核心,聯合文件系統
    d51ce1c2e575: Pull complete 
    c2344adc4858: Pull complete 
    fcf3ceff18fc: Pull complete 
    16da0c38dc5b: Pull complete 
    b905d1797e97: Pull complete 
    4b50d1c6b05c: Pull complete 
    c75914a65ca2: Pull complete 
    1ae8042bdd09: Pull complete 
    453ac13c00a3: Pull complete 
    9e680cd72f08: Pull complete 
    a6b5dc864b6c: Pull complete 
    Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6          # 簽名
    Status: Downloaded newer image for mysql:latest 
    docker.io/library/mysql:latest                 # 真實地址
    

    刪除鏡像

    docker rmi 刪除鏡像

    docker rmi [OPTIONS] IMAGE [IMAGE...]
    
    [root@hwh1 ~]# docker rmi --help 
    Usage:	docker rmi [OPTIONS] IMAGE [IMAGE...]
    Remove one or more images
    Options:
      -f, --force      Force removal of the image        強制刪除鏡像
          --no-prune   Do not delete untagged parents    不刪除未標記的父類
    
    
    # 刪除指定鏡像
    [root@hwh1 ~]# docker rmi mysql 
    Untagged: mysql:latest
    Untagged: mysql@sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6
    Deleted: sha256:be0dbf01a0f3f46fc8c88b67696e74e7005c3e16d9071032fa0cd89773771576
    Deleted: sha256:086d66e8d1cb0d52e9337eabb11fb9b95960e2e1628d90100c62ea5e8bf72306
    Deleted: sha256:f37c61ee1973b18c285d0d5fcf02da4bcdb1f3920981499d2a20b2858500a110
    Deleted: sha256:e40b8bca7dc63fc8d188a412328e56caf179022f5e5d5b323aae57d233fb1069
    Deleted: sha256:339f6b96b27eb035cbedc510adad2560132925a835f0afddbcc1d311c961c14b
    Deleted: sha256:d38b06cdb26a5c98857ddbc6ef531d3f57b00e325c0c314600b712efc7ff6ab0
    Deleted: sha256:09687cd9cdf4c704fde969fdba370c2d848bc614689712bef1a31d0d581f2007
    Deleted: sha256:b704a4a65bf536f82e5d8b86e633d19185e26313de8380162e778feb2852011a
    Deleted: sha256:c37206160543786228aa0cce738e85343173851faa44bb4dc07dc9b7dc4ff1c1
    Deleted: sha256:12912c9ec523f648130e663d9d4f0a47c1841a0064d4152bcf7b2a97f96326eb
    Deleted: sha256:57d29ad88aa49f0f439592755722e70710501b366e2be6125c95accc43464844
    Deleted: sha256:b17c024283d0302615c6f0c825137da9db607d49a83d2215a79733afbbaeb7c3
    Deleted: sha256:13cb14c2acd34e45446a50af25cb05095a17624678dbafbcc9e26086547c1d74
    
    # 遞歸刪除(批量刪除)
    [root@hwh1 ~]# docker rmi -f $(docker images -aq)
    Untagged: hello-world:latest
    Untagged: hello-world@sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
    Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
    # 已全部刪除
    [root@hwh1 ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    
    

    容器命令

    注:下載一個 centos 鏡像測試

    新建容器並啟動

    docker run 新建容器並啟動

    [root@hwh1 ~]# docker pull centos
    Using default tag: latest
    latest: Pulling from library/centos
    8a29a15cefae: Pull complete 
    Digest: sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700
    Status: Downloaded newer image for centos:latest
    docker.io/library/centos:latest
    
    docker run
    
    [root@hwh1 ~]# docker run --help 
    Usage:	docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    Run a command in a new container
    Options:
          -d, --detach                     Run container in background and print 
                                              container ID                           後台方式運行
          --name string                    Assign a name to the container            容器名字,來區分容器
          -i, --interactive                Keep STDIN open even if not attached      使用交互方式,進入容器查詢內容
          -t, --tty                        Allocate a pseudo-TTY                     使用交互方式,進入容器查詢內容
          -p, --publish list               Publish a container's port(s) to the host 指定容器端口 
              -p 主機端口:容器端口
              -p 容器端口
              -p ip:主機端口:容器端口
              容器端口
          -P, --publish-all                Publish all exposed ports to random ports 隨機端口
          
    
    # 啟動並進入容器,相當於一個小型虛擬機
    [root@hwh1 ~]# docker run  -it centos /bin/bash
    [root@af833bdd3acf /]# ls      # 基礎版 centos 很多命令都不完善
    bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    [root@af833bdd3acf /]# exit    # 退出命令
    exit
    

    列出所有正在運行的容器

    docker ps 列出所有正在運行的容器

    docker ps [OPTIONS]
    
    [root@hwh1 ~]# docker ps --help
    Usage:	docker ps [OPTIONS]
    List containers
    Options:
      -a, --all             Show all containers (default shows just running)           列出所有的容器,包括正在運行和停止的
      -f, --filter filter   Filter output based on conditions provided                 
          --format string   Pretty-print containers using a Go template
      -n, --last int        Show n last created containers (includes all states)       列出最近運行的容器
                            (default -1)
      -l, --latest          Show the latest created container (includes all states)    显示最後創建的容器
          --no-trunc        Don't truncate output                                      不截斷輸出
      -q, --quiet           Only display numeric IDs                                   只显示数字 ID
      -s, --size            Display total file sizes                                   显示文件總大小
    
    
    [root@hwh1 ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    a0f986785f33        centos              "/bin/bash"         7 seconds ago       Up 5 seconds                            nervous_agnesi
    [root@hwh1 ~]# docker ps -n=1
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    a0f986785f33        centos              "/bin/bash"         6 minutes ago       Up 6 minutes                            nervous_agnesi
    [root@hwh1 ~]# docker ps -q
    a0f986785f33
    

    退出容器

    exit             # 直接容器停止並退出
    Ctrl + P + Q     # 不停止容器退出(快捷鍵)
    

    刪除容器

    docker rm 刪除容器

    docker rm [OPTIONS] CONTAINER [CONTAINER...]
    
    [root@hwh1 ~]# docker rm --help 
    Usage:	docker rm [OPTIONS] CONTAINER [CONTAINER...]
    Remove one or more containers
    Options:
      -f, --force     Force the removal of a running container (uses SIGKILL)      強制刪除正在運行的容器
      -l, --link      Remove the specified link                                    刪除指定的鏈接
      -v, --volumes   Remove anonymous volumes associated with the container       刪除與容器關聯的匿名卷
    
    [root@hwh1 ~]# docker rm af833bdd3acf      刪除已經停止的
    af833bdd3acf
    [root@hwh1 ~]# docker rm -f a0f986785f33   刪除正在運行的容器
    a0f986785f33
    
    # docker ps -a -q|xargs docker rm    # 刪除所有的容器,使用管道符
    

    啟動和停止容器操作

    docker start id       # 啟動
    docker restart id     # 重啟
    docker stop id        # 停止當前正在運行的容器
    docker kill id        # 強制停止當前容器
    
    [root@hwh1 ~]# docker start 7b28015cd7f6
    7b28015cd7f6
    [root@hwh1 ~]# docker restart 7b28015cd7f6
    7b28015cd7f6
    [root@hwh1 ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
    7b28015cd7f6        centos              "/bin/bash"         46 seconds ago      Up 9 seconds                                 unruffled_wiles
    e2ff2fee0669        bf756fb1ae65        "/hello"            12 days ago         Exited (0) 12 days ago                       amazing_nightingale
    690a9f41c7a8        bf756fb1ae65        "/hello"            12 days ago         Exited (0) 12 days ago                       zealous_blackwell
    [root@hwh1 ~]# docker stop 7b28015cd7f6
    7b28015cd7f6
    [root@hwh1 ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS              NAMES
    7b28015cd7f6        centos              "/bin/bash"         57 seconds ago      Exited (0) 2 seconds ago                      unruffled_wiles
    e2ff2fee0669        bf756fb1ae65        "/hello"            12 days ago         Exited (0) 12 days ago                         amazing_nightingale
    690a9f41c7a8        bf756fb1ae65        "/hello"            12 days ago         Exited (0) 12 days ago       
    

    常用的其他命令

    後台啟動容器

    # docker run -d 鏡像名
    [root@hwh1 ~]# docker run -d centos
    9e34ebe17e41fb762f535ab21d81240b5fb4b105a44ed13c8813a8a8978f9b27
    # 問題:
    # docker ps -a,發現服務停止了
    # 常見的坑:
    # docker 容器使用後台運行,就必須要有要一個前台進程,docker發現沒有應用,就會自動停止
    

    查看日誌

    docker logs [OPTIONS] CONTAINER
    
    [root@hwh1 ~]# docker logs --help
    Usage:	docker logs [OPTIONS] CONTAINER
    Fetch the logs of a container
    Options:
          --details        Show extra details provided to logs                         显示額外的詳細信息
      -f, --follow         Follow log output                                           跟蹤日誌輸出
          --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or     從時間戳開始显示
                           relative (e.g. 42m for 42 minutes)
          --tail string    Number of lines to show from the end of the logs (default   日誌显示行數
                           "all")
      -t, --timestamps     Show timestamps                                             显示時間戳
          --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37)     在時間戳之前显示日誌
                           or relative (e.g. 42m for 42 minutes)
    

    查看容器中進程信息

    docker top CONTAINER [ps OPTIONS]
    
    [root@hwh1 ~]# docker top --help 
    Usage:	docker top CONTAINER [ps OPTIONS]
    Display the running processes of a container
    
    # docker top 容器id
    [root@hwh1 ~]# docker top 147f08710d27
    UID                 PID                 PPID                C                   STIME   
    root                76123               76105               0                   21:13  
    

    查看鏡像的元數據

    docker inspect [OPTIONS] NAME|ID [NAME|ID...]
    
    [root@hwh1 ~]# docker inspect --help 
    Usage:	docker inspect [OPTIONS] NAME|ID [NAME|ID...]
    Return low-level information on Docker objects
    Options:
      -f, --format string   Format the output using the given Go template          用 Go 模板打印出一個圖像
      -s, --size            Display total file sizes if the type is container      如果類型是容器的話,就显示容器大小
          --type string     Return JSON for specified type                         返回指定類型的 JSON 字符串
    
    # 查看 centos 的元數據
    [root@hwh1 ~]# docker inspect 147f08710d27
    [
        {
            "Id": "147f08710d2732d81ee9ce2680a7cfad48cbd186e87e27b081d82c103a29f084",
            "Created": "2020-06-15T13:13:13.783652979Z",
            "Path": "/bin/bash",
            "Args": [],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 76123,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2020-06-15T13:13:15.632825635Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
            "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee",
            "ResolvConfPath": "/var/lib/docker/containers/147f08710d2732d81ee9ce2680a7cfad48cbd186e87e27b081d82c103a29f084/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/147f08710d2732d81ee9ce2680a7cfad48cbd186e87e27b081d82c103a29f084/hostname",
            "HostsPath": "/var/lib/docker/containers/147f08710d2732d81ee9ce2680a7cfad48cbd186e87e27b081d82c103a29f084/hosts",
            "LogPath": "/var/lib/docker/containers/147f08710d2732d81ee9ce2680a7cfad48cbd186e87e27b081d82c103a29f084/147f08710d2732d81ee9ce2680a7cfad48cbd186e87e27b081d82c103a29f084-json.log",
            "Name": "/dazzling_benz",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "",
            "ExecIDs": null,
            "HostConfig": {
                "Binds": null,
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "json-file",
                    "Config": {}
                },
                "NetworkMode": "default",
                "PortBindings": {},
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": false,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "Capabilities": null,
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "private",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": [],
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DeviceCgroupRules": null,
                "DeviceRequests": null,
                "KernelMemory": 0,
                "KernelMemoryTCP": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": null,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/asound",
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],
                "ReadonlyPaths": [
                    "/proc/bus",
                    "/proc/fs",
                    "/proc/irq",
                    "/proc/sys",
                    "/proc/sysrq-trigger"
                ]
            },
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/74794286462edce8a73f8e74239c0229d6cec3afac92f052951245d91e05c7cd-init/diff:/var/lib/docker/overlay2/ae0a1afad34903571dd0df8a39bc4bea93ccd793ae2f6185fa95385c18d56f05/diff",
                    "MergedDir": "/var/lib/docker/overlay2/74794286462edce8a73f8e74239c0229d6cec3afac92f052951245d91e05c7cd/merged",
                    "UpperDir": "/var/lib/docker/overlay2/74794286462edce8a73f8e74239c0229d6cec3afac92f052951245d91e05c7cd/diff",
                    "WorkDir": "/var/lib/docker/overlay2/74794286462edce8a73f8e74239c0229d6cec3afac92f052951245d91e05c7cd/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [],
            "Config": {
                "Hostname": "147f08710d27",
                "Domainname": "",
                "User": "",
                "AttachStdin": true,
                "AttachStdout": true,
                "AttachStderr": true,
                "Tty": true,
                "OpenStdin": true,
                "StdinOnce": true,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                ],
                "Cmd": [
                    "/bin/bash"
                ],
                "Image": "centos",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {
                    "org.label-schema.build-date": "20200114",
                    "org.label-schema.license": "GPLv2",
                    "org.label-schema.name": "CentOS Base Image",
                    "org.label-schema.schema-version": "1.0",
                    "org.label-schema.vendor": "CentOS",
                    "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
                    "org.opencontainers.image.licenses": "GPL-2.0-only",
                    "org.opencontainers.image.title": "CentOS Base Image",
                    "org.opencontainers.image.vendor": "CentOS"
                }
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "dcbcaf21dc6395481ce4c27bd58e83b306aee13216f852b4ac92edab13dc6698",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {},
                "SandboxKey": "/var/run/docker/netns/dcbcaf21dc63",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "1b8456cbbb162e74762144d5a13305ba84acb45db92ce2467c0bc15724077b72",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "23077e8fffbf9407b9d83e492e05cc11904b4dbf7fd3ab3a4b84c36c1a7ee4a5",
                        "EndpointID": "1b8456cbbb162e74762144d5a13305ba84acb45db92ce2467c0bc15724077b72",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    

    進入當前正在運行的容器

    # 我們通常容器都是使用後台方式運行的,需要進入容器,修改一些配置
    # 方式一 :docker exec -it 容器id bashShell
    # 進入容器后開啟一個新的終端,可以在裏面操作(常用)
    # docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    
    [root@hwh1 ~]# docker exec --help 
    Usage:	docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    Run a command in a running container
    Options:
      -d, --detach               Detached mode: run command in the background             在後台運行命令
          --detach-keys string   Override the key sequence for detaching a container      重寫用於分離容器的鍵序列
      -e, --env list             Set environment variables                                設置環境變量
      -i, --interactive          Keep STDIN open even if not attached                     即使沒有連接,也保持STDIN打開
          --privileged           Give extended privileges to the command                  授予命令擴展權限
      -t, --tty                  Allocate a pseudo-TTY                                    分配一個偽TTY
      -u, --user string          Username or UID (format: <name|uid>[:<group|gid>])       用戶名或者 id
      -w, --workdir string       Working directory inside the container                   容器內的工作目錄
      
    
    [root@hwh1 ~]# docker exec -it a41c80fd6d1c /bin/bash
    [root@a41c80fd6d1c /]# ls
    bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    
    
    # 方式二 :docker attach 容器id
    # 進入容器正在執行的終端,不會啟動新的終端
    # docker attach [OPTIONS] CONTAINER
    
    [root@hwh1 ~]# docker attach --help 
    Usage:	docker attach [OPTIONS] CONTAINER
    Attach local standard input, output, and error streams to a running container
    Options:
          --detach-keys string   Override the key sequence for detaching a container       重寫用於分離容器的鍵序列
          --no-stdin             Do not attach STDIN                                       不要附加STDIN
          --sig-proxy            Proxy all received signals to the process (default true)  將所有接收到的信號代理到進程(默認為true)
    
    
    [root@hwh1 ~]# docker attach a41c80fd6d1c
    [root@a41c80fd6d1c /]# ls
    bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    

    拷貝文件

    # 從容器被拷貝文件到主機上
    # docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-               docker cp 容器id:容器內路徑 目的的主機路徑
    
    # 從主機上拷貝文件到容器
    # docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH               docker cp 主機路徑 容器id:目的的容器內路徑
    
    [root@hwh1 ~]# docker cp --help 
    Usage:	docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
        	docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
    Copy files/folders between a container and the local filesystem
    
    Use '-' as the source to read a tar archive from stdin
    and extract it to a directory destination in a container.
    Use '-' as the destination to stream a tar archive of a
    container source to stdout.
    
    Options:
      -a, --archive       Archive mode (copy all uid/gid information)  存檔模式(複製所有uid/gid信息)
      -L, --follow-link   Always follow symbol link in SRC_PATH        始終遵循容器內路徑中的符號鏈接
    
    # 從容器被拷貝文件到主機上
    [root@hwh1 home]# docker attach a41c80fd6d1c
    [root@a41c80fd6d1c /]# cd /home
    [root@a41c80fd6d1c home]# ls
    [root@a41c80fd6d1c home]# touch hwh.java               # 在 home 目錄下創建一個  hwh.java
    [root@a41c80fd6d1c home]# ls
    hwh.java
    [root@hwh1 home]# ls
    hwh  hwh1  hwh2  user01  user02
    [root@hwh1 home]# docker cp a41c80fd6d1c:/home/hwh.java /home           # 將 hwh.java 複製到主機上
    [root@hwh1 home]# ls
    hwh  hwh1  hwh2  hwh.java  user01  user02
    
    

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案