Accumulo入門手冊
來自: http://www.nosqldb.cn/1373093083484.html
1。介紹
Apache Accumulo的是一個高度可擴展的結構化存儲,基于谷歌的BigTable。Accumulo是用Java編寫的,并在Hadoop分布式文件系統 (HDFS),這是流行的Apache Hadoop項目的一部分工作。Accumulo支持高效存儲和檢索的結構化數據,包括查詢范圍,并提供支持使用Accumulo表作為輸入和輸出的 MapReduce作業。
Accumulo設有自動負載平衡和分區,數據壓縮和細粒度的安全標簽。
2。Accumulo設計
2.1。數據模型
Accumulo提供了豐富的數據模型不是簡單的鍵 - 值存儲,但不是完全的關系數據庫。數據表示為鍵 - 值對,其中鍵和值是由以下元素:
Key |
Value |
|
Row ID |
Column |
Timestamp |
Family |
Qualifier |
Visibility |
鍵和值的所有元素都表示為字節數組時間戳,這是一個長期的除外。Accumulo各種鍵的元素和字典升序排列。時間戳以遞減順序排序,首先出現在一個連續的掃描,以便以后的版本相同的密鑰。表由一組排序鍵 - 值對。
2.2。體系結構
accumulo是一個分布式數據存儲和檢索系統,因此由一些建筑元件,其中一些許多單獨服務器上運行的。大部分的工作確實涉及Accumulo保持一定性能的數據,如組織,可用性和完整性,在許多商品級機。
2.3。組件
一個實例的Accumulo包括的許多TabletServers,一個垃圾收集過程中,一臺主服務器和多個客戶端。
2.3.1。tablet服務器
TabletServer 管理一些子集的所有片(分區表)。這包括接收從客戶端中寫道,堅持預寫日志,寫入新的鍵值對排序在內存中,定期沖洗排序鍵 - 值對HDFS中的新文件,并響應來自客戶端的讀取,形成一個合并排序查看所有鍵和值從創建和排序的內存中存儲的所有文件。
TabletServers執行恢復以前的服務器失敗,重新應用發現任何寫在預寫日志平板平板。
2.3.2。垃圾收集器
Accumulo進程將共享存儲在HDFS中的文件。每隔一段時間,垃圾收集器將確定不再需要任何進程的文件,并刪除它們。
2.3.3。master
是 負責檢測和響應TabletServer失敗的Accumulo master。它試圖以平衡負載分配藥片仔細和指導TabletServers的卸載片,必要時跨TabletServer的。master確保所有分片 被分配到每一個TabletServer,并處理表的創建,修改和刪除請求從客戶。master也協調啟動,正常關機和恢復的變化的預寫日志tablet 服務器時失敗。
可能會運行多個master。master將選舉一個作為master,其他作為備份。
2.3.4。客戶
Accumulo包括鏈接到每一個應用程序的客戶端庫。客戶端庫包含邏輯尋找管理某個特定的平板電腦,服務器和通信與TabletServers寫入和檢索鍵 - 值對。
2.4。數據管理
Accumulo 存儲表中的數據,這是劃分成片。片分區行邊界,這樣一個特定的行的所有列和值一起被發現在同一片劑。主片分配到一個TabletServer的時間。這使 行級交易采取不使用分布式鎖或其他一些復雜的同步機制。隨著客戶的插入和查詢數據,機器從集群中添加和刪除,主遷移片來保證他們就仍然可以采集和查詢負載 平衡群集。
2.5。tablet服務
寫 在TabletServer到達時,它被寫入到一個預寫日志,然后插入稱為MemTable中一個排序的數據結構在內存中。當MemTable對達到一定 規模的TabletServer寫道排序鍵 - 值對在HDFS中的文件被稱為索引順序訪問方法(ISAM)文件。這個過程被稱為一個小壓實。然后創建一個新的MemTable中預寫日志記錄和壓實的事 實。
當 一個請求讀取數據在TabletServer到達的,TabletServer確實二進制搜索以及整個MemTable中每個ISAM文件在內存中的相關 指標,找到相關的值。如果客戶端執行掃描,幾個鍵 - 值對返回給客戶端為了從MemTable中ISAM文件集進行合并排序,因為他們是閱讀。
2.6。壓實
為了管理文件,每片的數量,定期TabletServer的執行主要壓實tablet內的文件,其中一些ISAM文件合并成一個文件。最終將被刪除以前的文件,由垃圾收集器。這也提供了一個機會,用來徹底刪除鍵 - 值對省略鍵 - 值對創建新的文件時,刪除條目抑制。
2.7。拆分
當 創建一個表,它有一個平板電腦。隨著表的增長,其最初的平板電腦最終分裂成兩片。它可能是這些藥片將遷移到另一臺平板電腦服務器。如上表持續增長,及其片 劑將繼續分裂和遷移。的決定是基于自動分割片劑的片劑的大小的文件。片劑分割的大小閾值配置的每個表。除了自動分裂,用戶可以手動添加的分割點,用來從表 中創建新的片劑。手動分裂一個新表可以并行的讀取和寫入操作提供更好的初始性能,而無需等待自動分割。
當數據從表中刪除,平板電腦可能會萎縮。隨著時間的推移,這可能會導致空或小片。為了處理這個問題,片劑合并被引入在1.4 Accumulo。這在后面更詳細討論。
2.8。容錯
如果TabletServer失敗,法師檢測,并自動從故障服務器分配到其他服務器重新分配片。任何鍵 - 值對,在內存中的時間TabletServer失敗自動重新應用預寫式日志,以防止丟失任何數據。
法師將協調預寫日志復制到HDFS,以便提供給所有tablet服務器日志。為了使回收效率,更新在日志分組的平板電腦。注定的牌位,他們現在被分配給從排序的日志,可以快速申請TabletServers突變。
TabletServer故障都注意到法師的監控頁面,通過http://master-address:50095/monitor
訪問的 。
3。Accumulo shell
Accumulo提供了一個簡單的shell,可以用來檢查表的內容和配置設置,插入/更新/刪除值,更改配置設置。
外殼可以開始下面的命令:
$ACCUMULO_HOME/bin/accumulo shell -u [username]
shell會提示輸入相應的密碼到指定的用戶名,然后顯示以下提示:
Shell - Apache Accumulo Interactive Shell - - version 1.5 - instance name: myinstance - instance id: 00000000-0000-0000-0000-000000000000 - - type 'help' for a list of available commands -
3.1。基本管理
Accumulo shell可以用來創建和刪除表,以及配置表和實例的具體選項。
root@myinstance> tables !METADATA
root@myinstance> createtable mytable
root@myinstance mytable>
root@myinstance mytable> tables !METADATA mytable
root@myinstance mytable> createtable testtable
root@myinstance testtable>
root@myinstance testtable> deletetable testtable
root@myinstance>殼牌也可以用來插入更新和掃描表。這是非常有用的檢查表。root@myinstance mytable> scanroot@myinstance mytable> insert row1 colf colq value1 insert successfulroot@myinstance mytable> scan row1 colf:colq [] value1
括號內的數值“[]”的知名度標簽。由于沒有被使用,這是該行空。您可以使用“-ST”掃描到細胞內,也看到時間戳選項。
3.2。表維護
compact命令指示Accumulo安排鞏固和刪除哪些文件項被刪除的表壓實。
root@myinstance mytable> compact -t mytable 07 16:13:53,201 [shell.Shell] INFO : Compaction of table mytable scheduled for 20100707161353EDT
該flush命令指示Accumulo寫當前內存中的所有條目,對于一個給定的表到磁盤。
root@myinstance mytable> flush -t mytable 07 16:14:19,351 [shell.Shell] INFO : Flush of table mytable initiated...
3.3。用戶管理
shell可用于添加,刪除,并授予用戶特權。
root@myinstance mytable> createuser bob Enter new password for 'bob': ********* Please confirm new password for 'bob': *********
root@myinstance mytable> authenticate bob Enter current password for 'bob': ********* Valid
root@myinstance mytable> grant System.CREATE_TABLE -s -u bob
root@myinstance mytable> user bob Enter current password for 'bob': *********
bob@myinstance mytable> userpermissions System permissions: System.CREATE_TABLE Table permissions (!METADATA): Table.READ Table permissions (mytable): NONE
bob@myinstance mytable> createtable bobstable bob@myinstance bobstable>
bob@myinstance bobstable> user root Enter current password for 'root': *********
root@myinstance bobstable> revoke System.CREATE_TABLE -s -u bob
4。寫作Accumulo客戶端
4.1。運行客戶端代碼
有多種方式運行的Java代碼使用Accumulo的。下面列出的不同的方式來執行客戶端代碼。
使用Java可執行文件
使用accumulo腳本
使用該工具的腳本
為 了運行客戶端代碼編寫對Accumulo運行,您將需要包括罐子Accumulo取決于你的classpath。Accumulo客戶端的代碼依賴于 Hadoop和飼養員。對于Hadoop的Hadoop的核心罐子,在Hadoop的lib目錄下的所有的罐子,conf目錄到classpath中。飼 養員3.3,你只需要添加飼養員罐,也不是什么在飼養員的lib目錄。您可以運行下面的命令上的配置Accumulo系統,看看有什么使用它的類路徑。
$ACCUMULO_HOME/bin/accumulo classpath
運行你的代碼的另一種選擇是把一個jar文件 $ ACCUMULO_HOME / lib / ext目錄
。這樣做后,你可以使用accumulo的腳本來執行你的代碼。例如,如果你創建一個jar含有類com.foo.Client,放置在lib / ext目錄
,那么你可以使用命令 $ ACCUMULO_HOME / bin中/ accumulo com.foo.Client的
執行代碼。
如果你正在寫的地圖減少,訪問Accumulo,那么你可以使用的bin / tool.sh的腳本來運行這些作業的工作。查看地圖減少的例子。
4.2。連
所有客戶端必須先識別Accumulo例如,他們將進行通信。做到這一點的代碼如下:
String instanceName = "myinstance";String zooServers = "zooserver-one,zooserver-two"Instance inst = new ZooKeeperInstance(instanceName, zooServers);Connector conn = inst.getConnector("user", "passwd");
4.3。寫入數據
通過創建對象代表所有更改的列單排突變數據寫入到Accumulo的。這些變化是由原子在TabletServer。客戶端,然后將它提交給適當的TabletServers到BatchWriter突變。
突變可以創建這樣的:
Text rowID = new Text("row1");Text colFam = new Text("myColFam");Text colQual = new Text("myColQual");ColumnVisibility colVis = new ColumnVisibility("public");long timestamp = System.currentTimeMillis();Value value = new Value("myValue".getBytes());Mutation mutation = new Mutation(rowID); mutation.put(colFam, colQual, colVis, timestamp, value);
4.3.1。BatchWriter
高度優化的BatchWriter送突變的多個TabletServers和自動批次突變攤銷網絡開銷相同TabletServer注定。必須小心避免的任何傳遞給BatchWriter對象改變的內容,因為它保持內存中的對象,而配料。
添加到BatchWriter突變是這樣的:
long memBuf = 1000000L; // bytes to store before sending a batchlong timeout = 1000L; // milliseconds to wait before sendingint numThreads = 10;BatchWriter writer = conn.createBatchWriter("table", memBuf, timeout, numThreads) writer.add(mutation); writer.close();
一個例子可以發現在使用批處理寫 accumulo/docs/examples/README.batch
4.4。讀取數據
Accumulo優化,快速檢索與給定鍵關聯的值,并有效返回連續鍵及其關聯值范圍。
4.4.1。掃描器
檢索數據,客戶端使用掃描儀,它的作用像一個迭代器鍵和值。掃描儀可以被配置在特定的鍵來啟動和停止,并返回可用的列的一個子集。
// specify which visibilities we are allowed to seeAuthorizations auths = new Authorizations("public");Scanner scan = conn.createScanner("table", auths); scan.setRange(new Range("harry","john")); scan.fetchFamily("attributes");for(Entry<Key,Value> entry : scan) { String row = entry.getKey().getRow(); Value value = entry.getValue(); }
4.4.2。隔離式掃描儀
Accumulo支持能力提出了一個孤立的觀點的行掃描時。有三種可能的方式,行可能會改變accumulo:
一個突變應用于一個表
或大或小的壓實的一部分執行的迭代器
批量導入新文件
隔 離擔保,所有這些操作的行上所做的更改或無被看見。使用IsolatedScanner孤立的觀點的一個accumulo表取得。當使用常規的掃描儀,它 是可以看到一排的非孤立的觀點。例如,如果一個突變修改分三路,它可能是你只會看到兩個修改。對于隔離掃描儀要么全部三個的變化被視為或無。
該IsolatedScanner緩沖行客戶端上的,所以不會大排平板服務器崩潰。默認情況下,行緩存在內存中,但用戶可以方便地提供自己的緩沖區,如果他們想緩沖到磁盤時行大。
舉一個例子,看看
examples/simple/src/main/java/org/apache/accumulo/examples/simple/isolation/InterferenceTest.java
4.4.3。BatchScanner
對于某些類型的訪問,它是更有效的同時檢索幾個范圍。出現這種情況,當訪問一組不連續的行,其ID已檢索,例如從二級索引。
類 似該BatchScanner配置到掃描器,它可以被配置為檢索可用的列的一個子集,但是,而不是通過一個單一的范圍,BatchScanners接受一 組范圍。重要的是要注意,鍵由BatchScanner返回鍵以排序的順序,因為流式傳輸是從多個TabletServers平行。
ArrayList<Range> ranges = new ArrayList<Range>();// populate list of ranges ...BatchScanner bscan = conn.createBatchScanner("table", auths, 10); bscan.setRanges(ranges); bscan.fetchFamily("attributes");for(Entry<Key,Value> entry : scan) System.out.println(entry.getValue());
一個例子可以發現在accumulo/docs/examples/README.batch
4.5。代理
代理API允許Java以外的語言與Accumulo互動。在代碼庫中提供代理服務器和一個客戶端可以進一步產生。
4.5.1。Prequisites
代理服務器可以住在任何節點上的基本客戶端API將工作。這意味著它必須是能夠溝通的法師,飼養員,NameNode的數據節點。代理客戶端只需要與代理服務器進行通信的能力。
4.5.2。組態
代理服務器的配置選項里面住的屬性文件。最起碼,你需要提供以下屬性:
protocolFactory=org.apache.thrift.protocol.TCompactProtocol$Factory tokenClass=org.apache.accumulo.core.client.security.tokens.PasswordToken port=42424 instance=test zookeepers=localhost:2181
在你的發行版,你可以找到一個示例配置文件:
$ACCUMULO_HOME/proxy/proxy.properties
這個配置文件示例演示備份代理服務器由MockAccumulo或MiniAccumuloCluster的的abilty。
4.5.3。運行代理服務器
控股配置屬性文件創建后,代理服務器就可以開始在Accumulo分布(假設你的屬性文件被命名為config.properties中)使用以下命令:
$ACCUMULO_HOME/bin/accumulo proxy -p config.properties
4.5.4。創建一個代理客戶端
除了安裝舊貨編譯的,你還需要生成客戶端代碼,語言舊貨安裝特定語言的庫。通常情況下,您的操作系統的軟件包管理器就能自動安裝這些你在預期的位置,如目錄/ usr / lib中/蟒蛇/節儉的site-packages /。
你可以找到節儉文件生成客戶端:
$ACCUMULO_HOME/proxy/proxy.thrift
生成客戶端后,在上述的配置屬性指定的端口將被用來連接到服務器。
4.5.5。使用代理客戶端
下面的例子已經寫在Java和方法簽名可能舊貨編譯器生成客戶端時指定的語言不同而略有差別。在初始化一個連接到代理服務器(Apache舊貨的文件連接到舊貨服務的例子),代理客戶機上的方法將可用。要做的第一件事就是登錄:
Map password = new HashMap<String,String>(); password.put("password", "secret");ByteBuffer token = client.login("root", password);
登錄后,返回的令牌將被使用到客戶端的后續調用。讓我們創建一個表,添加一些數據,表掃描,并刪除它。
首先,創建一個表。
client.createTable(token, "myTable", true, TimeType.MILLIS);
接下來,添加一些數據:
// first, create a writer on the serverString writer = client.createWriter(token, "myTable", new WriterOptions());// build column updatesMap<ByteBuffer, List<ColumnUpdate> cells> cellsToUpdate = //...// send updates to the serverclient.updateAndFlush(writer, "myTable", cellsToUpdate); client.closeWriter(writer);
掃描數據和批處理的服務器上返回的結果:
String scanner = client.createScanner(token, "myTable", new ScanOptions());ScanResult results = client.nextK(scanner, 100);for(KeyValue keyValue : results.getResultsIterator()) { // do something with results} client.closeScanner(scanner);
5。客戶開發
通常情況下,Accumulo包含許多移動部件。即使是一個單機版的Hadoop的Accumulo需要,動物園管理員,Accumulo高手,tablet服務器等,如果你想寫單元測試使用Accumulo的,你需要大量的基礎設施到位之前,你的測試可以運行。
5.1。模擬Accumulo
模擬Accumulo用品大部分的客戶端API模擬實現。它目前不強制用戶,登錄權限,等它支持迭代器和組合。請注意,MockAccumulo保存在內存中的所有數據,并不會保留任何數據或設置運行之間。
在正常情況下與Accumulo客戶端的交互看起來像這樣:
Instance instance = new ZooKeeperInstance(...);Connector conn = instance.getConnector(user, passwordToken);
要與MockAccumulo互動時,只需更換ZooKeeperInstance與MockInstance:
Instance instance = new MockInstance();
事實上,你可以使用選項-假
的Accumulo殼與MockAccumulo:
$ ./bin/accumulo shell --fake -u root -p '' Shell - Apache Accumulo Interactive Shell - - version: 1.5 - instance name: fake - instance id: mock-instance-id - - type 'help' for a list of available commands - root@fake> createtable test root@fake test> insert row1 cf cq value root@fake test> insert row2 cf cq value2 root@fake test> insert row3 cf cq value3 root@fake test> scan row1 cf:cq [] value row2 cf:cq [] value2 row3 cf:cq [] value3 root@fake test> scan -b row2 -e row2 row2 cf:cq [] value2 root@fake test>
當測試的Map Reduce作業,你還可以設置的的AccumuloInputFormat和AccumuloOutputFormat類的模擬Accumulo:
AccumuloInputFormat.setMockInstance(job, "mockInstance"); AccumuloOutputFormat.setMockInstance(job, "mockInstance");
5.2。mini Accumulo集群
雖 然模擬Accumulo的進行單元測試的客戶端API提供了一個輕量級的實施,往往是必要寫更現實的終端到終端的整合利用整個生態系統的測試。的迷你 Accumulo集群配置和啟動飼養員,初始化Accumulo,并開始主以及一些平板電腦服務器,使這成為可能。它的運行對本地文件系統,而不必啟動 HDFS。
啟動它,你將需要作為參數提供一個空的目錄和根密碼:
File tempDirectory = // JUnit and Guava supply mechanisms for creating temp directoriesMiniAccumuloCluster accumulo = new MiniAccumuloCluster(tempDirectory, "password"); accumulo.start();
一旦我們有我們的小集群運行,我們將要與客戶端API Accumulo:
Instance instance = new ZooKeeperInstance(accumulo.getInstanceName(), accumulo.getZooKeepers());Connector conn = instance.getConnector("root", new PasswordToken("password"));
完成后,我們的開發代碼,我們想關閉我們MiniAccumuloCluster:
accumulo.stop()// delete your temporary folder
6。表配置
Accumulo表中有幾個選項來改變默認行為,Accumulo以及存儲的數據的基礎上提高性能,可以配置。這些措施包括地方團體,約束,盛開的過濾器,迭代器和塊緩存。
6.1。地址組
Accumulo套柱家庭支持存儲在磁盤上分開,以允許客戶端有效地掃描是經常一起使用,以避免掃描列家庭不要求列。地址組設置后,會自動利用掃描儀和BatchScanner操作時,他們的fetchColumnFamilies()方法用于。
默認情況下,表放置到同一個“默認”本地組的所有列家庭。隨時可以配置其他地方團體通過shell或編程方式如下:
6.1.1。通過shell的管理地址組
usage: setgroups <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}} [-?] -t <table>
user@myinstance mytable> setgroups group_one=colf1,colf2 -t mytable
user@myinstance mytable> getgroups -t mytable
6.1.2。通過客戶端API地址組管理
Connector conn;HashMap<String,Set<Text>> localityGroups = new HashMap<String, Set<Text>>();HashSet<Text> metadataColumns = new HashSet<Text>(); metadataColumns.add(new Text("domain")); metadataColumns.add(new Text("link"));HashSet<Text> contentColumns = new HashSet<Text>(); contentColumns.add(new Text("body")); contentColumns.add(new Text("images")); localityGroups.put("metadata", metadataColumns); localityGroups.put("content", contentColumns); conn.tableOperations().setLocalityGroups("mytable", localityGroups);// existing locality groups can be obtained as followsMap<String, Set<Text>> groups = conn.tableOperations().getLocalityGroups("mytable");
列的家庭地址組的分配可以在任何時間改變。的物理移動到他們的新地址組的列家庭主要通過定期壓實過程,發生在后臺持續發生。主要壓實,也可如期通過shell立即生效:
user@myinstance mytable> compact -t mytable
6.2。約束
Accumulo支持突變在插入時的約束。這可以被用來根據用戶定義的策略禁止某些插入。不限突變不符合要求的約束被拒絕,并且發送回客戶端。
約束可以通過設置表屬性如下:
user@myinstance mytable> constraint -t mytable -a com.test.ExampleConstraint com.test.AnotherConstraint user@myinstance mytable> constraint -l com.test.ExampleConstraint=1 com.test.AnotherConstraint=2
目前,有沒有通用的約束與Accumulo分布。新的約束條件,可以創建通過編寫Java類實現org.apache.accumulo.core.constraints.Constraint接口的。
要部署一個新的約束,創建一個jar文件包含的類實施新的約束,并將其放置在lib目錄的Accumulo安裝。可以添加新的約束罐到Accumulo,不重新啟動的情況下啟動,但現有的約束類的任何改變需要重新啟動Accumulo。
約束的一個例子可以發現在 accumulo/docs/examples/README.constraints
相應的代碼,根據 accumulo/examples/simple/main/java/accumulo/examples/simple/constraints
。
6.3。Bloom過濾器
突變被應用到一個Accumulo表,每片創建幾個文件。如果盛開的過濾器被啟用,Accumulo將創建并加載到內存中的一個小的數據結構,以確定文件是否包含給定鍵在打開文件之前。這可以大大加快查找。
為了使盛開的過濾器,殼牌輸入以下命令:
user@myinstance> config -t mytable -s table.bloom.enabled=true
廣泛使用bloom過濾器的例子可以發現在accumulo/docs/examples/README.bloom
.。
6.4。迭代器
迭代器提供了一個模塊化的機制,用于將要執行的TabletServers功能進行掃描,或者數據壓縮。這使用戶能夠有效地總結,篩選和匯總數據。事實上,內置的單元級別的安全功能和列取使用迭代器來實現。一些有用的迭代器中所提供與Accumulo和中可以找到的 org.apache.accumulo.core.iterators.user
包。在每一種情況下,任何自定義的迭代器必須包括在Accumulo classpath中,通常包括一個罐子在$ ACCUMULO_HOME / lib中
或 $ ACCUMULO_HOME / lib / ext目錄
,雖然VFS類加載器允許類路徑操縱利用的各種計劃,包括網址和HDFS的URI 。
6.4.1。shell設置迭代
迭代器可以配置的桌子上掃描,小型壓實和/或主要壓實范圍。如果迭代實現的OptionDescriber接口,的setiter命令可用于交互的方式提示用戶提供值給予必要的選項。
usage: setiter [-?] -ageoff | -agg | -class <name> | -regex | -reqvis | -vers [-majc] [-minc] [-n <itername>] -p <pri> [-scan] [-t <table>]
user@myinstance mytable> setiter -t mytable -scan -p 15 -n myiter -class com.company.MyIterator
config命令可以隨時用于手動配置了Iterator不實施的OptionDescriber接口的情況下,這是非常有用的迭代器。
config -t mytable -s table.iterator.{scan|minc|majc}.myiter=15,com.company.MyIterator config -t mytable -s table.iteartor.{scan|minc|majc}.myiter.opt.myoptionname=myoptionvalue
6.4.2。設置迭代編程方式
scanner.addIterator(new IteratorSetting( 15, // priority "myiter", // name this iterator "com.company.MyIterator" // class name));
一些迭代器從客戶端代碼需要額外的參數,如下面的例子:
IteratorSetting iter = new IteratorSetting(...); iter.addOption("myoptionname", "myoptionvalue"); scanner.addIterator(iter)
表支持獨立的迭代器設置被應用在掃描時輕微壓實后,而主要壓實。對于大多數用途,表格將具有相同的所有三個迭代器設置,以避免不一致的結果。
6.4.3。版本迭代器和時間戳
Accumulo 提供版本的數據管理能力,通過使用時間戳內的關鍵。由客戶端創建的關鍵,如果沒有指定一個時間戳,然后系統將設置時間戳為當前時間。兩個鍵具有相同的 ROWID列,但不同的時間戳被認為是兩個版本的相同的密鑰。如果兩個插入相同的ROWID,列和時間戳制成accumulo的,則行為是不確定性。
時間戳以遞減順序排序,最新的數據是第一位的。accumulo可以配置為返回前k個版本,或版本高于給定的日期。默認是返回一個最新版本。
是可以改變的通過改變VersioningIterator選項如下的表的版本政策:
user@myinstance mytable> config -t mytable -s table.iterator.scan.vers.opt.maxVersions=3 user@myinstance mytable> config -t mytable -s table.iterator.minc.vers.opt.maxVersions=3 user@myinstance mytable> config -t mytable -s table.iterator.majc.vers.opt.maxVersions=3
創建表時,默認情況下,它的配置,使用VersioningIterator和保持一個版本。可以創建一個表不VersioningIterator NDI選項在shell。的Java API還具有以下的方法
connector.tableOperations.create(String tableName, boolean limitVersion)
邏輯時間
Accumulo 1.2引入邏輯時間的概念。這確保由accumulo設置時間戳永遠向前。這將有助于避免出現問題由TabletServers引起不同的時間設置。每片 計數器時間郵票每一個突變的基礎上給出了獨特的一。當使用時間以毫秒為單位,如果兩件事情同一毫秒內到達,然后都收到相同的時間戳。當使用時間(以毫秒為 單位),將accumulo設定的時間始終前進,永不后退。
表可以配置為使用邏輯在創建時的時間戳如下:
user@myinstance> createtable -tl logical
刪除
刪除特殊鍵accumulo得到沿將所有其他數據排序。當刪除鍵被插入時,accumulo將不顯示任何有時間戳小于或等于刪除鍵。在主要壓實,年紀比任何鍵刪除鍵被省略創建的新文件,并省略鍵作為正規的垃圾收集過程的一部分從磁盤上刪除。
6.4.4。過濾器
鍵 -值對的一組掃描時,它是通過一個過濾器的使用,可以將任意的過濾策略。過濾器是只返回鍵-值對滿足過濾邏輯的迭代器類型。Accumulo有幾個內置的 過濾器,可以配置任何表:ColumnAgeOff AgeOff,時間戳,NoVis,和正則表達式。可以添加更多通過編寫一個Java類擴展 org.apache.accumulo.core.iterators.Filter
類。
該AgeOff過濾器可以被配置為刪除的數據比目標日期或一個固定的時間量從本。下面的例子設置一個表中刪除插入超過30秒前的一切:
user@myinstance> createtable filtertest user@myinstance filtertest> setiter -t filtertest -scan -minc -majc -p 10 -n myfilter -ageoff AgeOffFilter removes entries with timestamps more than <ttl> milliseconds old ----------> set org.apache.accumulo.core.iterators.user.AgeOffFilter parameter negate, default false keeps k/v that pass accept method, true rejects k/v that pass accept method: ----------> set org.apache.accumulo.core.iterators.user.AgeOffFilter parameter ttl, time to live (milliseconds): 3000 ----------> set org.apache.accumulo.core.iterators.user.AgeOffFilter parameter currentTime, if set, use the given value as the absolute time in milliseconds as the current time of day: user@myinstance filtertest> user@myinstance filtertest> scan user@myinstance filtertest> insert foo a b c user@myinstance filtertest> scan foo a:b [] c user@myinstance filtertest> sleep 4 user@myinstance filtertest> scan user@myinstance filtertest>
看到一個表的迭代器設置,使用方法:
user@example filtertest> config -t filtertest -f iterator ---------+---------------------------------------------+------------------ SCOPE | NAME | VALUE ---------+---------------------------------------------+------------------ table | table.iterator.majc.myfilter .............. | 10,org.apache.accumulo.core.iterators.user.AgeOffFilter table | table.iterator.majc.myfilter.opt.ttl ...... | 3000 table | table.iterator.majc.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator table | table.iterator.majc.vers.opt.maxVersions .. | 1 table | table.iterator.minc.myfilter .............. | 10,org.apache.accumulo.core.iterators.user.AgeOffFilter table | table.iterator.minc.myfilter.opt.ttl ...... | 3000 table | table.iterator.minc.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator table | table.iterator.minc.vers.opt.maxVersions .. | 1 table | table.iterator.scan.myfilter .............. | 10,org.apache.accumulo.core.iterators.user.AgeOffFilter table | table.iterator.scan.myfilter.opt.ttl ...... | 3000 table | table.iterator.scan.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator table | table.iterator.scan.vers.opt.maxVersions .. | 1 ---------+---------------------------------------------+------------------
6.4.5。Combiners
Accumulo允許合路器上配置表和列家庭。合當它應用于跨股份ROWID列家庭和列預選賽任何鍵關聯的值。這是類似MapReduce的減少步驟,應用一些函數與特定鍵相關聯的所有的值。
例如,如果一個加法組合器被配置在桌子上,以下的突變,插入
Row Family Qualifier Timestamp Value rowID1 colfA colqA 20100101 1 rowID1 colfA colqA 20100102 1
該表將反映只有一個總價值:
rowID1 colfA colqA - 2
合路器可以使用一個表的setiter在shell命令啟用。下面就是一個例子。
root@a14 perDayCounts> setiter -t perDayCounts -p 10 -scan -minc -majc -n daycount -class org.apache.accumulo.core.iterators.user.SummingCombiner TypedValueCombiner can interpret Values as a variety of number encodings (VLong, Long, or String) before combining ----------> set SummingCombiner parameter columns, <col fam>[:<col qual>]{,<col fam>[:<col qual>]} : day ----------> set SummingCombiner parameter type, <VARNUM|LONG|STRING>: STRING
root@a14 perDayCounts> insert foo day 20080101 1 root@a14 perDayCounts> insert foo day 20080101 1 root@a14 perDayCounts> insert foo day 20080103 1 root@a14 perDayCounts> insert bar day 20080101 1 root@a14 perDayCounts> insert bar day 20080101 1
root@a14 perDayCounts> scan bar day:20080101 [] 2 foo day:20080101 [] 2 foo day:20080103 [] 1
Accumulo包括一些有用的組合器開箱。要找到這些看看在org.apache.accumulo.core.iterators.user
包。
可以添加額外的合路,通過創建一個Java類,延長 org.apache.accumulo.core.iterators.Combiner的
加入一罐含有該類到Accumulo的lib / ext目錄。
一個合成器的一個例子,可以發現
accumulo/examples/simple/main/java/org/apache/accumulo/examples/simple/combiner/StatsCombiner.java
6.5。塊緩存
為 了增加吞吐量的常用訪問的條目,,采用了Accumulo塊緩存。此塊緩存緩沖區內存中的數據,因此,它并沒有被讀出的磁盤。的RFile格式 Accumulo喜歡的組合索引塊和數據塊,索引塊是用來尋找相應的數據塊。典型的查詢Accumulo結果在多個索引塊的二進制搜索,然后通過線性掃描 的一個或多個數據塊。
塊緩存可配置每一個表的基礎上,在平板電腦上的服務器共享一個單一的資源池和所有藥片托管。要配置tablet服務器的塊高速緩存的大小,設置以下屬性:
tserver.cache.data.size:指定的高速緩存文件的數據塊的大小。 tserver.cache.index.size:指定文件索引的緩存的大小。
要啟用的塊緩存表,設置以下屬性:
table.cache.block.enable:確定是否啟用文件(數據)塊緩存。 table.cache.index.enable:確定是否啟用索引緩存。
塊緩存可以有一個顯著的效果,對緩解熱點問題,以及減少查詢延遲。它是默認啟用的元數據表。
6.6。壓實
當 數據被寫入到Accumulo緩存在內存中。緩沖在存儲器中的數據最終被寫入到HDFS上每片為基礎。文件也可以直接向片批量導入。tablet服務器在 后臺運行多個文件合并成一個主要的壓實。tablet服務器來決定哪片緊湊,平板電腦內的文件壓縮。作出這一決定是使用壓縮率,這是每一個表的基礎上進行 配置。要配置這個比例修改下列屬性:
table.compaction.major.ratio
增加這一比例將導致更多的文件每片和壓實工作。更多文件每片意味著更高的查詢延遲。因此,調整這個比例是一個權衡之間采集和查詢性能。缺省值為3的比例。
的比率的工作方式是,一組文件被壓縮到一個文件中,如果組中的文件的大小的總和是大于集合中的最大文件的大小的比值乘以。如果這是不是真正的平板電腦中的所有文件集,最大的文件被刪除考慮,剩余的文件被認為是壓實。這是重復,直到壓實被觸發或有考慮留下任何文件。
tablet服務器用來運行主要壓實的后臺線程的數量是可配置的。要配置此修改以下屬性:
tserver.compaction.major.concurrent.max
此外,tablet服務器使用小型壓實的線程數是可配置的。要配置此修改以下屬性:
tserver.compaction.minor.concurrent.max
正在運行和排隊的主要和次要的壓實的數字可見的Accumulo顯示器頁面。這可以讓你看到,如果壓實備份和上面的設置都需要調整。調整時可用的線程數,壓實,考慮如地圖和減少節點上運行的內核和其它任務的數量。
重 大壓實如果沒有跟上,那么的文件每片數將增長到一個點查詢性能開始受到影響。來處理這種情況的一種方法是,以增加壓縮比。例如,如果壓縮比被設置為1,則 每一個新的文件中添加一個平板輕微壓實立即隊列主要壓實片劑。因此,如果平板電腦擁有一個200M的文件和小型壓實寫入一個1M的文件,那么主要的壓實試 圖合并200M和1M的文件。如果平板電腦服務器有很多片劑試圖做這樣的事情,那么主要的壓實將備份和文件每片的數量將開始增長,假設數據被連續寫入。增 加壓實比例將緩解備份通過降低主要壓實工作需要做。
另一個選項來處理每片種植的文件太大調整以下屬性:
table.file.max
當 平板電腦達到這個數字刷新其內存中的數據保存到磁盤文件和需要,它會選擇做一個合并輕微壓實。合并輕微壓實,將平板電腦的最小文件合并輕微壓縮時間在內存 中的數據。因此,文件的數量不會超過這個限制增長。這將使小壓實需要更長的時間,這將導致攝取性能下降。這可能會導致攝取放慢主要壓實,直到有足夠的時間 趕上。當調整此屬性,也考慮調整壓縮率。理想的情況下,合并輕微的壓實永遠需要發生重大壓實會跟上。配置文件最大和壓實比只合并發生輕微壓實和主要壓實從 未發生,這是可能的。只因為這樣做合并小壓實導致O(? 2)要做的工作,這應該被避免。主要壓實完成的工作量是?(N *日志?(N)),其中 ?是壓縮率。
一 個表可以手動進行壓實。要啟動一個小的壓實,使用flush在shell命令。要發起一個重大的壓實,使用外殼緊湊命令。緊湊的命令將壓縮到一個文件中的 一個表中的所有片。即使同一個文件的平板電腦將被壓縮。一個主要壓實過濾器被配置為一個表的情況下,這是有用的。以1.4的壓縮能力的范圍內的一個表 中的溶液。要使用此功能指定啟動停止緊湊命令行。這將只壓縮片重疊在給定的行范圍。
6.7。預拆分表
將平衡Accumulo跨服務器和分發表。表之前,變大時,它會保持在單個服務器上作為一個單一的片劑。這限制了在該數據可以被添加或查詢的單個節點的速度的速度。為了提高性能,當一個表是新的,還是小的,你可以添加分割點,產生新的平板電腦。
在shell:
root@myinstance> createtable newTable root@myinstance> addsplits -t newTable g n t
這將創建一個新的表4粒。該表將被分割的字母“G”,“N”,“T”,這將很好地工作,如果該行數據與小寫字母字符開始。如果你的行數據包括二進制信息或數字信息,或者如果行信息的分布是不平坦的,那么你會選擇不同的分割點。現在采集和查詢可以進行4個節點可以提高性能。
6.8。合并片
隨 著時間的推移,一個表可以得到非常大,如此之大,它有數百成千上萬的分割點。一旦有足夠的片蔓延在整個集群中的一個表,額外的分裂可能不會提高性能,可能 會造成不必要的簿記。數據的分布可能會隨時間而改變。例如,如果行數據包含了最新的信息和數據的不斷增加和刪除,以維持目前的信息的一個窗口,為老年人行 的藥片可能是空的。
accumulo支持片劑合并,它可以被用來減少分割點的數目。下面的命令將所有行合并從“A”到“Z”成一個單一的平板電腦:
root@myinstance> merge -t myTable -s A -e Z
如果一個合并的結果產生一個大于配置的分割大小的片劑,片劑可能會被分割由數位板服務器。肯定會增加平板電腦大小的任何合并前,如果我們的目標是有較大的藥片:
root@myinstance> config -t myTable -s table.split.threshold=2G
為了合并小藥片,你可以問accumulo合并部分小于給定大小的表。
root@myinstance> merge -t myTable -s 100M
缺省情況下,小片將不會被合并到已經大于給定大小的片劑。這可以離開孤立的小藥片。要強制合并成較大的片小藥片使用“ - {} - force”選項:
root@myinstance> merge -t myTable -s 100M --force
合并分片上一節的時間。如果你的表中包含許多部分小分割點,或正在試圖改變分割整個表的大小,這將是更快地分割點設置和合并整個表:
root@myinstance> config -t myTable -s table.split.threshold=256M root@myinstance> merge -t myTable
6.9。刪除范圍
考慮索引方案使用最新的信息在每一行。例如“20110823-15:20:25.013的可能會對指定的日期和時間的行。在某些情況下,我們可能會喜歡這個日期的基礎上刪除行說,刪除所有的數據比當年舊。Accumulo支持刪除操作,有效地消除兩行之間的數據。例如:
root@myinstance> deleterange -t myTable -s 2010 -e 2011
這將刪除所有以“2010”開始的行,它會停在“2011”開始的任何行。您可以刪除任何數據,2011年之前:
root@myinstance> deleterange -t myTable -e 2011 --force
外殼不會允許你刪除一個無限的范圍內(不啟動),除非你提供的“ - {} - force”選項。
范圍的刪除是通過使用在給定的開始/結束位置的分割,而且會影響在表中的分割的數目。
6.10。克隆表
可 以創建一個新的表指向現有的表的數據。這是一個非常快的元數據操作,實際上沒有數據復制。克隆表和源表可以改變獨立后的克隆操作。這個功能的一個用例的測 試。例如,測試一個新的過濾迭代器,克隆表,添加過濾器的克隆,并迫使主要壓實。要執行測試數據較少,克隆一個表,然后使用刪除范圍,有效地去除很多從克 隆的數據。另一個用例生成一個快照,防范人為錯誤。要創建一個快照,克隆一個表,然后禁止克隆的寫權限。
克隆操作將指向源表的文件。這就是為什么flush選項默認情況下,在shell中存在并已啟用。如果沖洗選項未啟用,那么任何數據源表目前已在內存不存在克隆。
克隆表復制源表中的配置。然而,源表中的權限不會被復制到克隆。創建克隆后,只有用戶創建克隆可以讀取和寫入。
在以下示例中,我們可以看到,克隆操作之后插入的數據是不可見的克隆。
root@a14> createtable people root@a14 people> insert 890435 name last Doe root@a14 people> insert 890435 name first John root@a14 people> clonetable people test root@a14 people> insert 890436 name first Jane root@a14 people> insert 890436 name last Doe root@a14 people> scan 890435 name:first [] John 890435 name:last [] Doe 890436 name:first [] Jane 890436 name:last [] Doe root@a14 people> table test root@a14 test> scan 890435 name:first [] John 890435 name:last [] Doe root@a14 test>
du 命令在shell中顯示一個表被使用在HDFS多少空間。此命令也可以顯示在HDFS中有多少空間重疊的兩個克隆表。在下面的例子都顯示表CI是使用 428M。CI是克隆CIC和du表明這兩個表共享428M。經過三個條目插入CIC和其滿臉通紅,都顯示了這兩個表仍然共享428M,但中投公司本身有 226個字節。最后,表CIC被壓實,然后杜表明,每個表使用428M。
root@a14> du ci 428,482,573 [ci] root@a14> clonetable ci cic root@a14> du ci cic 428,482,573 [ci, cic] root@a14> table cic root@a14 cic> insert r1 cf1 cq1 v1 root@a14 cic> insert r1 cf1 cq2 v2 root@a14 cic> insert r1 cf1 cq3 v3 root@a14 cic> flush -t cic -w 27 15:00:13,908 [shell.Shell] INFO : Flush of table cic completed. root@a14 cic> du ci cic 428,482,573 [ci, cic] 226 [cic] root@a14 cic> compact -t cic -w 27 15:00:35,871 [shell.Shell] INFO : Compacting table ... 27 15:03:03,303 [shell.Shell] INFO : Compaction of table cic completed for given range root@a14 cic> du ci cic 428,482,573 [ci] 428,482,612 [cic] root@a14 cic>
6.11。表導出
Accumulo 支持導出表的表復制到另一個集群的目的。導出和導入表保留表配置,分裂,和邏輯的時間。表導出,然后復制通過的hadoop distcp命令。要導出表,它必須是離線和保持脫機而discp運行的。它需要保持脫機狀態的原因是為了防止文件被刪除。表可以克隆和克隆脫機序,以避 免失去對表的訪問。參見DOCS /例子/ README.export一個例子。
7。表設計
7.1。基本表
行 ID進行排序由于Accumulo表,每個表都可以被認為是被索引的行ID。行ID進行查找,可以快速執行,做一個二進制搜索,第一個沖過片,然后在平板 電腦。客戶應小心選擇行ID,以支持其所需的應用程序。一個簡單的規則是選擇行ID為每個實體的唯一標識符來存儲和分配所有其他屬性進行跟蹤,根據此行的 ID列。例如,如果我們有一個逗號分隔的文件中的下列數據:
userid,age,address,account-balance
我們可能會選擇此數據存儲使用的的ROWID,其余列家庭中的數據的userid:
Mutation m = new Mutation(new Text(userid)); m.put(new Text("age"), age); m.put(new Text("address"), address); m.put(new Text("balance"), account_balance); writer.add(m);作家。(米);
通過指定的用戶ID作為掃描儀的范圍和獲取特定的列,然后我們就可以檢索任何一個特定的用戶ID列:
Range r = new Range(userid, userid); // single rowScanner s = conn.createScanner("userdata", auths); s.setRange(r); s.fetchColumnFamily(new Text("age"));for(Entry<Key,Value> entry : s) System.out.println(entry.getValue().toString());
7.2。ROWID設計
通常,它是必要的,以便有預期的訪問模式最適合的方式,是命令行變換ROWID。一個很好的例子,這是互聯網域名的組成部分,以相同的父域組行的順序顛倒過來:
com.google.code com.google.labs com.google.mail com.yahoo.mail com.yahoo.research
有些數據可能會導致在創造非常大的行 - 行有許多列。在這種情況下,表設計可能要拆分這些行更好的負載平衡,同時保持他們在一起排序的掃描目的。這可以通過在該行的末尾附加一個隨機的子串:
com.google.code_00 com.google.code_01 com.google.code_02 com.google.labs_00 com.google.mail_00 com.google.mail_01
它也可以通過添加一個字符串表示的一段時間,如一周或一個月的日期:
com.google.code_201003 com.google.code_201004 com.google.code_201005 com.google.labs_201003 com.google.mail_201003 com.google.mail_201004
追加日期提供了一個給定的日期范圍限制掃描的附加功能。
7.3。索引
為 了支持通過查找一個實體的多個屬性,額外的索引可以建。然而,因為Accumulo表可以支持任意數量的列不事先指定的一個附加指標往往會在主表中的記錄 足以支持查找。在這里,該指數已為ROWID值或期限從主表,列的家庭都是一樣的,預選賽的索引表列包含從主表的ROWID。
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
Term |
Field Name |
MainRowID |
注:我們存儲的rowid列預選賽,而不是價值,這樣我們就可以有一個以上的ROWID與一個特定的期限內的指數相關。如果我們存儲這個值,我們只能看到一個值出現自Accumulo默認配置為返回一個最新的值與鍵關聯的那些行。
然后,可以通過先掃描索引表出現需要的值在指定的列,返回一個列表,從主表行ID查找。這些可以被用于檢索每個匹配的記錄,在他們的全部,或列的一個子集,從主表。
支 持高效查找多個從同一個表的rowid中,Accumulo客戶端庫提供一個BatchScanner。用戶可以指定一組范圍,在多個線程執行的查找到多 個服務器,并返回一個Iterator所有檢索的行BatchScanner。返回的行排序順序,不作為的情況下,基本的掃描儀接口。
// first we scan the index for IDs of rows matching our queryText term = new Text("mySearchTerm");HashSet<Text> matchingRows = new HashSet<Text>();Scanner indexScanner = createScanner("index", auths); indexScanner.setRange(new Range(term, term));// we retrieve the matching rowIDs and create a set of rangesfor(Entry<Key,Value> entry : indexScanner) matchingRows.add(new Text(entry.getKey().getColumnQualifier()));// now we pass the set of rowIDs to the batch scanner to retrieve themBatchScanner bscan = conn.createBatchScanner("table", auths, 10); bscan.setRanges(matchingRows); bscan.fetchFamily("attributes");for(Entry<Key,Value> entry : scan) System.out.println(entry.getValue());
動 態模式的Accumulo能力的優點之一是,不同的字段可以采集到同一物理表。但是,它可能有必要建立不同的索引表,如果不同的條款必須進行格式化, 以保持適當的排序順序。例如,實數必須比自己平時的符號不同的格式,以正確排序。在這些情況下,通常獨特的數據類型的每一個索引就足夠了。
7.4。實體屬性和圖形表
Accumulo是理想的存儲實體及其屬性的屬性,特別是稀疏。它往往是一起加入多個數據集,在同一表常見的實體。這可以允許的代表性的曲線圖,其中包括節點,它們的屬性,并且它連接到其他節點。
存儲個別事件,而非實體的屬性或圖形表存儲聚合信息的事件中所涉及的實體和實體之間的關系。單一事件時,不是非常有用,當隨意一個不斷更新的聚合,這通常是可取的。
實體 - 屬性或圖形表的物理架構如下:
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
EntityID |
Attribute Name |
Attribute Value |
Weight |
EntityID |
Edge Type |
Related EntityID |
Weight |
例如,要跟蹤員工,經理和產品以下實體屬性表可以使用。注意所用的權并不總是必要的,被設置為0時,不使用。
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
E001 |
name |
bob |
0 |
E001 |
department |
sales |
0 |
E001 |
hire_date |
20030102 |
0 |
E001 |
units_sold |
P001 |
780 |
E002 |
name |
george |
0 |
E002 |
department |
sales |
0 |
E002 |
manager_of |
E001 |
0 |
E002 |
manager_of |
E003 |
0 |
E003 |
name |
harry |
0 |
E003 |
department |
accounts_recv |
0 |
E003 |
hire_date |
20000405 |
0 |
E003 |
units_sold |
P002 |
566 |
E003 |
units_sold |
P001 |
232 |
P001 |
product_name |
nike_airs |
0 |
P001 |
product_type |
shoe |
0 |
P001 |
in_stock |
germany |
900 |
P001 |
in_stock |
brazil |
200 |
P002 |
product_name |
basic_jacket |
0 |
P002 |
product_type |
clothing |
0 |
P002 |
in_stock |
usa |
3454 |
P002 |
in_stock |
germany |
700 |
為了有效更新的邊權重,合計迭代器可以配置相同的密鑰應用的所有突變添加值。這些類型的表可以很容易地創建從原始事件,個別事件的實體,屬性和關系通過簡單的提取和插入鑰匙進入Accumulo各計數1。聚合迭代會照顧保持邊緣權重。
7.5。文件分區索引
用一個簡單的索引如上所述運作良好時,尋找匹配的記錄一組給定的標準之一。同時符合多個條件的記錄,如尋找文件包含所有的話時,當尋找'和'白'和'家',有幾個問題。
首先是必須被發送到客戶端,這會導致網絡流量的特定匹配的搜索條件中的任一項,該組的所有記錄。第二個問題是客戶端是負責執行的交集上套的記錄返回,以消除所有,但所有搜索條件匹配的記錄。內存的客戶端可能會在此操作過程中很容易被淹沒。
由于這些原因,Accumulo包括支持的方案被稱為分片索引,這些組操作可以被執行上面的TabletServers決定哪些記錄包括在結果集中的,可以在不產生網絡流量。
這是通過分割記錄成箱,每個駐留在至多一個TabletServer上,然后創建一個索引,每個記錄在每個垃圾桶如下:
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
BinID |
Term |
DocID |
Weight |
由 用戶定義的攝取應用映射到文件或記錄。存儲BinID的ROWID,我們確保特定斌的所有信息都包含在一個單一的平板電腦,并托管在一個單一的 TabletServer以來從未分裂Accumulo行跨片。存儲列家庭服務條款,使在這個垃圾桶的所有文件包含給定的長期快速查找。
最 后,我們進行交集操作,通過一個特殊的迭代器稱為相交迭代TabletServer。由于文件分割成許多垃圾桶,搜索所有文件必須搜索每一個垃圾桶。我們 可以使用BatchScanner,并行掃描所有的垃圾桶。相交迭代器應該啟用一個BatchScanner在用戶查詢代碼如下:
Text[] terms = {new Text("the"), new Text("white"), new Text("house")};BatchScanner bs = conn.createBatchScanner(table, auths, 20);IteratorSetting iter = new IteratorSetting(20, "ii", IntersectingIterator.class); IntersectingIterator.setColumnFamilies(iter, terms); bs.addScanIterator(iter); bs.setRanges(Collections.singleton(new Range()));for(Entry<Key,Value> entry : bs) { System.out.println(" " + entry.getKey().getColumnQualifier()); }
此 代碼有效的BatchScanner掃描一個表的所有平板電腦,尋找符合所有條款的文件。因為所有的平板電腦正在掃描的每個查詢,每個查詢比其他的 Accumulo掃描,這通常涉及少數TabletServers更加昂貴。這減少了支持的并發查詢數量和被稱為'掉隊'的問題,其中每一個查詢運行慢最 慢的服務器參與。
當然,快速的服務器將其結果返回給客戶端,它可以顯示給用戶,而他們等待的結果到達其余立即。如果結果是無序的,這是一個相當有效的到達第一的成績不如其他任何用戶。
8。高速攝取
accumulo經常被用來作為一個更大的數據處理和存儲系統的一部分。涉及Accumulo,攝取和查詢組件的并行系統性能發揮到極致的設計應提供足夠的并行和并發性,以避免產生瓶頸,為用戶和其他系統寫入和讀取Accumulo。有幾種方法,以實現高接收性能。
8.1。預拆分新表
新表包括默認情況下,一個單一的平板電腦。由于基因突變,表的增長和分裂成平衡由主跨TabletServers的多個片。這意味著總的攝取率將被限制在更少的服務器為群集內的,直到表中已經到了有是在每個TabletServer片其中。
預分割表,確保有盡可能多片隨意攝取前開始利用一切可能的并行集群硬件。表可以隨時拆分使用shell:
user@myinstance mytable> addsplits -sf /local_splitfile -t mytable
就提供并行攝取的目的,沒有必要創造更多的平板電腦比有物理機集群內合共攝取率是一個函數的物理機數量。請注意,合共攝取率仍然攝取客戶的機器上運行的數量,分布的rowid桌子對面的。的聚集攝取率將是次優的,如果有許多插入一個小數目的rowid。
8.2。多個Ingester客戶端
Accumulo 是能夠擴展的攝取率非常高,這是取決于有多少人TabletServers運轉中,但也攝取客戶的數量。這是因為單個客戶端,同時能配料突變和將它們發送 到所有TabletServers,是最終在一臺機器可以處理的數據的量限制。合共攝取率的客戶端數點在其中的總I / O的TabletServers或總的網絡帶寬容量達到線性擴展。
在高利率的攝取是最重要的操作設置,群集通常配置僅運行Ingester客戶奉獻一定數量的機器。客戶最佳的攝食率必要TabletServers,精確的比率會有所不同,根據每臺機器的資源和數據類型的分布。
8.3。大量攝取
Accumulo 支持的能力,如MapReduce的外部進程所產生的文件導入到現有的表。在某些情況下,它可能會更快加載數據,這種方式通過通過客戶使用 BatchWriters攝入而非。這使得大量的機器格式化數據的方式Accumulo預期。的新文件,然后簡單地介紹到Accumulo通過一個 shell命令。
要 配置的MapReduce準備批量加載數據格式化,作業應設置使用范圍分區工具,而不是默認的哈希分區工具。范圍分區工具使用分割點的Accumulo 表,將接收到的數據。分割點,可從外殼由MapReduce RangePartitioner的使用。請注意,這僅僅是有用的,如果現有的表已經分裂成多個片。
user@myinstance mytable> getsplits aa ab ac ... zx zy zz
運行MapReduce作業,使用創建文件的AccumuloFileOutputFormat被介紹給Accumulo的。一旦完成,文件可以添加到Accumulo通過殼:
user@myinstance mytable> importdirectory /files_dir /failures
需要注意的是引用的路徑是目錄,Accumulo運行在同一個HDFS實例。Accumulo將沒有任何文件被添加到指定的第二個目錄。
一個完整的例子,可以發現在使用大量攝取 accumulo /文檔/例子/ README.bulkIngest
8.4。散裝攝取的邏輯時間
邏 輯的時間是非常重要的大宗進口數據,客戶端代碼可能會選擇一個時間戳。在批量導入時,用戶可以選擇被導入文件的集合時間,以使邏輯。當它的啟 用,Accumulo使用迭代次批量導入的文件中懶洋洋地設置一個專門的系統。這種機制確保了時間不同步多節點應用程序(如運行MapReduce的)將 保持一定的因果順序的假象。這減輕了問題的時間是錯誤的系統上創建該文件批量導入。導入該文件時,這些時間都沒有設置,但只要它是讀取掃描或壓實。進口, 在一段時間內獲得和總是使用由專門的系統迭代設置時間。
的時間戳分配的accumulo將在該文件中的每一個鍵是相同的。這可能會導致問題,如果文件中包含多個密鑰是相同的時間戳除外。在這種情況下,按鍵的排序順序是不確定的。這可能發生,如果在同一批量導入文件插入和更新。
8.5。MapReduce的攝取
這 是可能的,以有效地寫入許多突變Accumulo的平行的方式從一個MapReduce作業。在這種情況下被寫入MapReduce的數據處理,住在 HDFS中,寫突變Accumulo使用AccumuloOutputFormat的。見的MapReduce下節分析的詳細信息。
使用MapReduce的一個例子可以找到根據accumulo/docs/examples/README.mapred
9。Google Analytics(分析)
Accumulo支持更先進的數據處理不是簡單的保持按鍵的排序和執行高效的查找。Google Analytics(分析)可以開發使用MapReduce和配合Accumulo表中的迭代器。
9.1。MapReduce的
Accumulo 表可以作為MapReduce作業的源和目標。與MapReduce作業要使用Accumulo的表(特別是新的Hadoop的API版本0.20),作 業參數配置,使用AccumuloInputFormat AccumuloOutputFormat。通過這兩種格式類Accumulo具體參數可以設置,做到以下幾點:
輸入驗證并提供用戶憑據
限制掃描一定范圍的行
限制輸入可用列的一個子集
9.1.1。mapper和reducer類
要閱讀從Accumulo表與下面的類的參數,并創建一個映射請務必配置AccumuloInputFormat的。
class MyMapper extends Mapper<Key,Value,WritableComparable,Writable> { public void map(Key k, Value v, Context c) { // transform key and value data here } }
要 寫入一個Accumulo表,與下面的類的參數,并創建一個減速請務必配置AccumuloOutputFormat的。從減速機發射的關鍵標識被發送到 的表的突變。這允許一個單一的減速寫信給一個以上的表,如果需要的。一個默認的表可以使用AccumuloOutputFormat配置,在這種情況下, 在輸出表的名稱沒有被傳遞到減速機內的上下文對象。
class MyReducer extends Reducer<WritableComparable, Writable, Text, Mutation> { public void reduce(WritableComparable key, Iterable<Text> values, Context c) { Mutation m; // create the mutation based on input key and value c.write(new Text("output-table"), m); } }
通過為輸出文本對象應包含表的名稱應采用這種突變。文本可以是空的,在這種情況下,突變將被應用到默認指定表名在AccumuloOutputFormat股權。
9.1.2。AccumuloInputFormat選擇
Job job = new Job(getConf()); AccumuloInputFormat.setInputInfo(job, "user", "passwd".getBytes(), "table", new Authorizations()); AccumuloInputFormat.setZooKeeperInstance(job, "myinstance", "zooserver-one,zooserver-two");
可選設置:
Accumulo限制到一組行范圍:
ArrayList<Range> ranges = new ArrayList<Range>();// populate array list of row ranges ...AccumuloInputFormat.setRanges(job, ranges);
accumulo限制到一個列表的列:
ArrayList<Pair<Text,Text>> columns = new ArrayList<Pair<Text,Text>>();// populate list of columnsAccumuloInputFormat.fetchColumns(job, columns);
使用正則表達式來匹配行IDs:
AccumuloInputFormat.setRegex(job, RegexType.ROW, "^.*");
9.1.3. AccumuloOutputFormat options
boolean createTables = true;String defaultTable = "mytable"; AccumuloOutputFormat.setOutputInfo(job, "user", "passwd".getBytes(), createTables, defaultTable); AccumuloOutputFormat.setZooKeeperInstance(job, "myinstance", "zooserver-one,zooserver-two");
可選設置:
AccumuloOutputFormat.setMaxLatency(job, 300); // millisecondsAccumuloOutputFormat.setMaxMutationBufferSize(job, 5000000); // bytes
一個示例使用MapReduce和Accumulo可以發現accumulo/docs/examples/README.mapred
d
9.2。合路
許多應用程序都可以從中受益的能力,總價值跨越常用鍵。這是可以做到通過合路器的迭代器,和類似的減少MapReduce的步驟。這提供了定義在線增量更新的分析能力,沒有面向批處理的MapReduce作業相關的開銷或延遲。
所有這一切都需要一個表的總價值來識別字段值將被分組,插入突變與這些領域的關鍵,組合迭代器支持所需的總結操作和配置表。
結合迭代的唯一限制是,組合開發人員不應該承擔所有的值給定鍵已經看到,由于新的突變可以隨時插入。這排除了如計算平均值時,例如在聚合中使用的值的總數。
9.2.1。特征向量
相 結合的迭代器范圍內Accumulo的表的一個有趣的用途是存儲用于在機器學習算法的特征矢量。例如,許多算法,如k-means聚類,支持向量機,異常 檢測等使用特征向量的概念和計算距離度量學習一個特定的模式。可用于列中一個Accumulo表中有效地存儲稀疏特征和他們的重量,以通過使用一個組合的 迭代器進行增量更新。
9.3。統計建模
需要更新,由多臺機器上并行的統計模型,可以類似地存儲范圍內Accumulo表。例如,可以有一個MapReduce的工作是一個全球性的統計模型迭代更新每個地圖,或降低了工作人員的工作參考通過一個嵌入式Accumulo的客戶端被讀取和更新的模型零件的。
使用Accumulo這樣小塊的信息,在隨機存取模式,這是相輔相成的MapReduce的順序訪問模式實現高效,快速的查找和更新。
10。安全
Accumulo 延伸BigTable的數據模型來實現的安全機制被稱為單元級別的安全。每一個鍵 - 值對都有自己的安全標簽,存儲的密鑰,該密鑰是用來確定一個給定的用戶是否滿足安全要求的值讀列下的可見性元素。這使得數據被存儲在同一行內的多種安全級 別,以及不同程度的訪問相同的表查詢的用戶,同時保持數據的機密性。
10.1。安全標簽表達式
當突變的應用,用戶可以指定一個安全標簽的每個值。這樣做是通過一個ColumnVisibility對象的put()方法創建的突變:
Text rowID = new Text("row1");Text colFam = new Text("myColFam");Text colQual = new Text("myColQual");ColumnVisibility colVis = new ColumnVisibility("public");long timestamp = System.currentTimeMillis();Value value = new Value("myValue");Mutation mutation = new Mutation(rowID); mutation.put(colFam, colQual, colVis, timestamp, value);
10.2。安全標簽表達式語法
防偽標簽由一組所需要的值讀標簽是與用戶定義的令牌。可以指定所需的令牌的集合,支持的令牌的邏輯“與”和“或”的組合,以及嵌套組的令牌一起使用的語法。
例如,假設在我們的組織,我們希望我們的數據值標簽防偽標簽用戶角色定義。我們可能已經令牌,如:
管理員 審計 系統
這些可以單獨指定,或結合使用邏輯運算符:
/ /用戶必須具有管理員權限: 管理員
/ /用戶必須具有管理員和審核權限 管理審計
/ / admin或審計權限的用戶 管理|審計
/ /用戶必須具有審計和管理員或系統中的一個或兩個 (管理系統)及審計
當|
與
運營商的使用,必須使用括號來指定優先級的運算符。
10.3。授權
當客戶端試圖讀取數據從Accumulo,任何防偽標簽進行檢查對集時掃描儀或BatchScanner的創建通過客戶端代碼的授權。如果授權被確定為不足,以滿足安全標簽,該值被抑制結果發送回給客戶端的一組。
指定授權用戶擁有令牌作為一個逗號分隔的列表:
// user possesses both admin and system level accessAuthorization auths = new Authorization("admin","system");Scanner s = connector.createScanner("table", auths);
10.4。用戶授權
每個accumulo用戶具有一組相關聯的安全性標簽。要操縱這些在shell中使用setuaths和getauths命令。這些也可以使用java安全操作API修改。
當用戶創建了一個掃描儀,通過一組授權。如果傳遞到掃描儀的授權用戶授權的一個子集,然后將拋出一個異常。
為了防止用戶寫他們無法讀取數據,添加的知名度約束到表中。使用EVC選項的CREATETABLE shell命令啟用此約束。對于現有的表使用下面的shell命令到啟用的知名度約束。確保約束不與任何現有的約束沖突。
config -t table -s table.constraint.1=org.apache.accumulo.core.security.VisibilityConstraint
ALTER TABLE權限的任何用戶可以添加或刪除此約束。此約束并不適用于大容量導入數據,如果這是一個關注,然后禁用批量的進口許可。
10.5。安全授權處理
對 于許多用戶提供服務的應用程序,它并不期望將創建一個accumulo用戶,每個應用程序用戶。在這種情況下,任何的應用程序的用戶所需要的所有授權的 accumulo用戶必須被創建。服務查詢,應用程序應該創建一個掃描儀應用程序用戶的授權。這些授權可以得到可信的第三方。
生 產系統通常將整合公共密鑰基礎設施(PKI)和指定的客戶端代碼在查詢使用PKI服務器層進行談判,以驗證用戶身份并獲取授權令牌(憑據)。這要求用戶指 定所必需的信息,來驗證自己的系統。用戶身份一旦建立,他們的憑據可以訪問客戶端代碼及用戶之所及之外傳遞給Accumulo,。
10.6。查詢服務層
由 于的主要方法的互動與Accumulo是通過Java API,生產環境中經常調用的執行查詢層。這可以通過在容器中使用Web服務的Apache Tomcat這樣的,但不是必需的。查詢服務層提供面向用戶的應用程序可以建立一個平臺,提供了一種機制。這允許應用程序設計者隔離潛在的復雜的查詢邏 輯,并執行基本的安全功能提供了一種方便點。
一些生產環境,選擇在這一層,用戶標識符用于檢索的訪問憑據,然后緩存在查詢層,并提交到Accumulo通過授權機制來實現認證。
通常情況下,查詢服務層位于在Accumulo和用戶工作站之間。
11。管理
11.1。硬件
因為我們正在運行的基本上是兩個或三個同時整個集群分層系統:HDFS,Accumulo和MapReduce,這是典型的由4至8核心,8到32 GB RAM的硬件。這是這樣每個正在運行的過程中可以有至少一個芯和2 - 4 GB的。
運行HDFS的核心之一,通常可以保持2至4個磁盤忙,所以每臺機器可能通常為2×300GB硬盤和多達4個1TB或2TB磁盤。
低 于這一標準,如與1U服務器2芯和4GB每個是可以做到的,但在這種情況下,建議只運行每臺機器上的兩個過程 - 即的DataNode和TabletServer的或的DataNode和MapReduce的工人,但不所有三個。這里的約束是有足夠的可用堆空間,一 臺機器上的所有進程。
11.2。網絡
Accumulo通過遠程過程調用兩個傳遞數據和控制信息通過TCP / IP進行通信。此外,Accumulo使用HDFS客戶溝通與HDFS。為了達到良好的采集和查詢性能,足夠的網絡帶寬必須可任意兩臺機器之間。
11.3。安裝
選擇目錄安裝Accumulo。這個目錄將被引用環境變量$ ACCUMULO_HOME
。運行以下命令:
$ tar xzf accumulo-assemble-1.5.0-bin.tar.gz # unpack to subdirectory $ mv accumulo-assemble-1.5.0-bin $ACCUMULO_HOME # move to desired location
在群集內的每臺機器重復此步驟。通常情況下,所有的機器有相同的$ ACCUMULO_HOME
。
11.4。依賴關系
Accumulo 需要HDFS,ZooKeeper的配置和運行開始之前。密碼應配置SSH至少Accumulo主和TabletServer機之間。在集群中運行網絡時 間協議(NTP),以確保節點的時鐘,不要太脫節,這可能會導致自動時間戳數據的問題,這也是一個不錯的主意。
11.5。組態
Accumulo配置編輯幾個殼牌和XML文件中發現 $ ACCUMULO_HOME / conf目錄
。其結構類似于Hadoop的配置文件。
11.5.1。編輯機密/ accumulo的env.sh
Accumulo需要知道在哪里可以找到它依賴于軟件。編輯accumulo env.sh指定以下內容:
輸入的安裝目錄Accumulo為
ACCUMULO_HOME美元
的位置輸入您系統的Java回家
$ JAVA_HOME
Hadoop的輸入位置為
$ HADOOP_HOME
選擇的位置Accumulo日志,并將其輸入
$ ACCUMULO_LOG_DIR“
輸入的ZooKeeper為
ZOOKEEPER_HOME美元
的位置
通過默認Accumulo TabletServers被設置為使用1GB的內存。你可能會改變這個通過改變價值$ ACCUMULO_TSERVER_OPTS
。注意語法是Java的JVM命令行選項。此值應小于物理內存的運行TabletServers機器。
有主人的內存使用和垃圾收集過程中的類似選項。如果他們超出物理RAM的硬件,減少這些,增加他們的物理RAM的范圍內,如果一個進程失敗,因為內存不足。
請 注意,您將指定Java堆空間,在accumulo env.sh。您應確保總的堆空間用于Accumulo TSERVER和在Hadoop的DataNode和TaskTracker必須是小于集群中的每個從節點上的可用內存。大型集群上,建議,都可以在不同 的機器上運行Hadoop的NameNode的Accumulo主,次要的NameNode,和Hadoop JobTracker的允許他們使用更多的堆空間。如果您運行的是一小簇在同一臺機器上,同樣確保他們的堆空間設置適合于可用的內存。
11.5.2。集群規范
在機器將作為的Accumulo主:
寫
$ ACCUMULO_HOME / conf目錄/碩士
文件Accumulo主的IP地址或域名。寫的機器,這將是在
$ ACCUMULO_HOME / conf目錄/奴隸
,每行一個TabletServers的IP地址或域名。
請注意,如果使用域名而不是IP地址,DNS必須配置正確參與集群中的所有機器。DNS可以是一個混亂的錯誤源。
11.5.3。Accumulo設置
指定適當的值ACCUMULO_HOME元/ conf目錄/ accumulo的site.xml
中的下列設置:
<property> <name>zookeeper</name> <value>zooserver-one:2181,zooserver-two:2181</value> <description>list of zookeeper servers</description></property>
這使找到的ZooKeeper Accumulo。Accumulo使用ZooKeeper的協調過程,并有助于敲定TabletServer失敗之間設置的。
<property> <name>walog</name> <value>/var/accumulo/walogs</value> <description>local directory for write ahead logs</description></property>
Accumulo預寫日志記錄所有變更表,然后將它們提交到表。“walog設置指定預寫日志寫入到每臺機器上的本地目錄。這個目錄應該存在所有機器上作為TabletServers的。
<property> <name>instance.secret</name> <value>DEFAULT</value></property>
實例需要一個秘密,使服務器之間的安全通信。配置你的秘密,并確保不向其他用戶可讀,的site.xml accumulo的
文件是。
可以修改某些設置通過Accumulo外殼,并立即生效,但一些設置需要一個過程重新啟動才能生效。有關詳細信息,請參閱“配置文件(可在監視器上的網頁)。
11.5.4。部署配置
復制的主人,奴隸,env.sh accumulo,如果有必要,accumulo的site.xml從$ ACCUMULO_HOME / conf目錄/
所有的機器的奴隸文件中指定主目錄。
11.6。初始化
必須初始化Accumulo創建的結構,它在內部使用定位數據在集群。HDFS是必須要配置和運行之前Accumulo可以初始化。
HDFS開始后,可以進行初始化通過執行 $ ACCUMULO_HOME /bin/ accumulo的初始化
。這個腳本會提示輸入名稱此實例Accumulo。實例名稱是用來確定一套表和特定于實例的設置。然后,該腳本將一些信息寫入到HDFS,所以Accumulo可以正常啟動。
初始化腳本會提示你設置root密碼。一旦Accumulo初始化后,就可以開始。
11.7。運行
11.7.1。從Accumulo開始
確保上配置的Hadoop集群中的所有機器,包括訪問共享HDFS實例。確保HDFS,ZooKeeper的運行。請確保ZooKeeper的配置和集群中的至少一臺計算機上運行。啟動Accumulo使用BIN /
start-all.sh
腳本。
為了驗證,運行Accumulo,檢查“狀態”頁面監控下 。此外,shell可提供一些信息表通過讀取元數據表的狀態。
11.7.2。停止Accumulo
要正常關機,運行的BIN /stop-all.sh
和主協調所有的tablet服務器關機。的關機等待完成所有的小壓實,所以它可能需要一些時間為特定的配置。
11.8。監控
主Accumulo監測的Accumulo組件的狀態和健康提供了一個接口。這個接口可以訪問指著Web瀏覽器http://accumulomaster:50095/status
11.9。記錄
Accumulo處理每寫一組日志文件。默認情況下,這些被發現下 $ ACCUMULO /logs/
。
11.10。恢復
關閉Accumulo TabletServer故障或錯誤的情況下,有些突變可能不會一直未成年人正確壓縮到HDFS。在這種情況下,將自動重新Accumulo這種突變的預寫日志時,片從故障服務器重新分配由主,在一個單一的TabletServer故障的情況下,或下一次啟動Accumulo,在發生故障時,關機期間。
要求預寫日志記錄器復制到HDFS進行恢復。復制日志,他們還整理,使平板電腦可以很容易地找到他們失蹤的更新。在Accumulo監控狀態頁顯示每個文件的復制/排序狀態。一旦恢復完成涉及任何片應回到``在線“狀態,到那時,這些藥片將無法給客戶。
Accumulo客戶端庫配置重試失敗的突變,并在許多情況下,客戶將能夠繼續處理后的恢復過程中,沒有拋出任何異常。