老师在办公室被躁在线观看 記錄一次 Hbase 線上問題的分析息争決

老师在办公室被躁在线观看

内行好,我是明哥!

本篇著述,我們回顧一次 hbase 線上問題的分析息争決 - KeyValue size too large,總結下背后的知識點,并共享一下放哨開源組件不同版块差異點的要领。

但愿内行有所收獲,謝謝内行!

01 Hbase 簡介

Hbase 作為 hadoop database, 是一款開源,漫衍式易擴展,面向大數據場景的,多版块,非關系型,數據庫搞定系統,是 Google Bigtable 的 JAVA 版開源實現。

Hbase 的底層存儲引擎是 HDFS,不错在等闲商業級服務器硬件(即常說的 x86 架構的服務器)的基礎上,提供對超大表(表的數據量不错有百萬行,每行的列數不错有百萬級)的隨機實時讀寫訪問。

Hbase具有以下特征:老师在办公室被躁在线观看

模塊化的線性擴展性; 強一致性并發讀寫复古; 可确立的表的自動 sharding; 表分區在 RegionServer 間的自動 failover; 基于 Block cache 和 Bloom 過濾器的實時讀取; 基于 server 端過濾器的查詢謂詞下推;

恰是因為 Hbase 的上述特征,Hbase 在各行各業有許多線上應用案列,不错說是 NoSql 數據庫的一個典型代表:

在各種超大數據量級 在需要實時并發讀寫复古 在表的結構比較靈活(即有好多荒芜列:有好多行和好多列,但每一溜只须眾多列中的少數列有值) 筆者就在車聯網場景下重度使用過 Hbase

題外話:

Nosql 數據庫有幾大類,幾個典型代表是:Hbase, ElasticSearch, MongoDb;

有個风趣风趣的現象,筆者發現國內 Hbase 使用的多,而國外似乎 Cassandra 使用的多。

02 一次線上 Hbase 問題的問題現象

某線上應用使用了 Hive 到 Hbase 的映射表,在使用 insert overwrite 從 hive 表查詢數據并插入 HBASE 表時,發生了錯誤。

通過放哨 HIVE 背后 YARN 上的作業的日记老师在办公室被躁在线观看,發現主要錯誤信息是 java.lang.IllegalArgumentException: KeyValue size too large,詳細報錯截屏和日记如下:

2020-04-08 老师在办公室被躁在线观看09:34:38,120 ERROR [main] ExecReducer: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) {"key":{"_col0":"0","_col1":"","_col2":"2020-04-08","_col3":"joyshebaoBeiJing","_col4":"105","_col5":"北京,"},"value":null}     at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:253)     at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:444)     at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392)     at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)     at java.security.AccessController.doPrivileged(Native Method)     at javax.security.auth.Subject.doAs(Subject.java:422)     at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1924)     at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158) Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.IllegalArgumentException: KeyValue size too large     at org.apache.hadoop.hive.ql.exec.GroupByOperator.processOp(GroupByOperator.java:763)     at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:244)     ... 7 more Caused by: java.lang.IllegalArgumentException: KeyValue size too large     at org.apache.hadoop.hbase.client.HTable.validatePut(HTable.java:1577)     at org.apache.hadoop.hbase.client.BufferedMutatorImpl.validatePut(BufferedMutatorImpl.java:158)     at org.apache.hadoop.hbase.client.BufferedMutatorImpl.mutate(BufferedMutatorImpl.java:133)     at org.apache.hadoop.hbase.client.BufferedMutatorImpl.mutate(BufferedMutatorImpl.java:119)     at org.apache.hadoop.hbase.client.HTable.put(HTable.java:1085)     at org.apache.hadoop.hive.hbase.HiveHBaseTableOutputFormat$MyRecordWriter.write(HiveHBaseTableOutputFormat.java:146)     at org.apache.hadoop.hive.hbase.HiveHBaseTableOutputFormat$MyRecordWriter.write(HiveHBaseTableOutputFormat.java:117)     at org.apache.hadoop.hive.ql.io.HivePassThroughRecordWriter.write(HivePassThroughRecordWriter.java:40)     at org.apache.hadoop.hive.ql.exec.FileSinkOperator.processOp(FileSinkOperator.java:717)     at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:815)     at org.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:84)     at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:815)     at org.apache.hadoop.hive.ql.exec.GroupByOperator.forward(GroupByOperator.java:1007)     at org.apache.hadoop.hive.ql.exec.GroupByOperator.processAggr(GroupByOperator.java:818)     at org.apache.hadoop.hive.ql.exec.GroupByOperator.processKey(GroupByOperator.java:692)     at org.apache.hadoop.hive.ql.exec.GroupByOperator.processOp(GroupByOperator.java:758)     ... 8 more 
03 該線上 Hbase 問題的問題原因

其實以上作業的報錯日记還是比較詳細的:Caused by: java.lang.IllegalArgumentException: KeyValue size too large at org.apache.hadoop.hbase.client.HTable.validatePut(HTable.java:1577);

即報錯詳細信息是:KeyValue size too large; 報錯來自 Hbase (而不是 HIVE)的類,從類名看是 hbase 客戶端在對待插入數據校驗時發現了錯誤:org.apache.hadoop.hbase.client.HTable.validatePut(HTable.java:1577);

熟识 Hbase 的小伙伴(其實不熟识 Hbase 的小伙伴,也能從報錯信息和報錯類上猜到一點點),從以上信息能夠猜到,是 Hbase 對每條記錄的 KyeValue 的大小做了抑制,當實際插入的 KeyValue 的大小超過該大小抑制閾值時,就會報上述錯誤。

什么是 KeyValue 呢?

這触及到 Hbase 的存儲結構,Hbase 內部是通過 KeyValue 結構來存儲表數據的; 好像上内行不错認為:某個 KeyValue 對應的是 Hbase 大寬表中的某行的某列; 每個 KeyVlue 內部內容包含:rowKey+CF(ColumnFamily)+CQ(Column qualifier)+Timestamp+Value; 詳細說明見官方文檔,截圖如下:

Hbase 為什么要抑制每個 KeyValue 的大小呢?老师在办公室被躁在线观看

究其原因,是因為 Hbase 需要在 hdfs 存儲引擎(基于分磁盤)之上提供對數據實時讀寫的复古; Hbase 在內部數據讀寫時使用了 LSM 數據結構 (Log-Structured-Merge Tree),這背后触及到了大批對內存的使用(讀數據時使用 BlockCache,寫數據時使用 memStore),也触及到了內存數據的異步 flush 和 hfile 文献的異步 compaction;(當然為了容錯,又触及到了 wal Hlog); 因為触及到基于內存提供對數據讀寫的复古,是以需要抑制使用的內存的總大小,由于內存 BlockCache 中緩存的數據是以Block 為單位的,而Block內部存儲的是一個個 KeyValue, 是以從細節來講也需要抑制每個 KeyValue的大小; 這里的 Block 是 Hbase的倡导,不是 HDFS Block; (Hbase 每個 Block 的默認大小是 64KB,欧美人与动牲交xxxxbbbb HDFS 每個BLOCK的默認大小一般是 128MB); 04 該線上 Hbase 問題的擴展知識-不同 Hbase 版块相關的參數

Hbase 作為一個流行的 Nosql數據庫,推出十多年來,当今有多個經典版块:

0.98;-- 該版块比較老了,部分遺留線上應用還有使用該版块的; 1.2.x;(1.4.x) -- 1.2.x 和 1.4.x 都是1.x 系列下用的比較多的穩定版块 2.1.x(2.4.x) -- 2.1.x 和 2.4.x 都是2.x系列下用的比較多的穩定版块 3.0.0-alpha-1 -- 3.x 系列当今還不是穩定版

對應該 “KeyValue size too large” 問題,不同版块推出了不同的相關參數:

在hbase-1.4 已往的版块中,(包括hbase 1.2.0-cdh5.14.2 和 hbase 1.2.0-cdh5.16.2),只须一個客戶端參數 hbase.client.keyvalue.maxsize; 在 hbase-1.4 及以后版块中,除了該客戶端參數 hbase.client.keyvalue.maxsize,還有一個服務端參數 hbase.server.keyvalue.maxsize;

其實,由于筆者并沒有持續跟進 HBASE 社區對 feautre 和 issue相關的討論(大部分使用者可能都不會),是以亦然在查閱不同版块的官方文檔時寄望到了上述細節,然后通過在土产货 IDEA 中使用 git->show history 對比不同版块 HBASE 中 hbase-default.xml 的源碼,進而確認到了JIRA記錄號,并在JIRA中確認了這點:

老师在办公室被躁在线观看

正如該 JIRA 中描绘:

HBASE-18043:

For sake of service protection we should not give absolute trust to clients regarding resource limits that can impact stability, like cell size limits. We should add a server side configuration that sets a hard limit for individual cell size that cannot be overridden by the client. We can keep the client side check, because it's expensive to reject a RPC that has already come in.

是以,不同版块中碰到不恻隐況,可能會包的錯誤主要有兩個:

情況1:Hbase KeyValue size too large 情況2:Cell with size 25000046 exceeds limit of 10485760 bytes

報錯情況一和報錯情況而,問題原因如下:

迄今为止,制造业仍然是物联网的最大采用者。它有助于提高自动化程度,提供对整个制造操作的可见性,并减少创新的上市时间。如果有可能为某个参数创建一个传感器,就有可能应用物联网技术来改善一个流程。物联网的一些应用是相当耐人寻味的。据预测,物联网将在这十年中引发另一场工业革命。

報錯情況一:沒有确立客戶端參數 hbase.client.keyvalue.maxsize,且實際插入的 keyvalue 的大小超過了該客戶端參數的默認大小抑制;

報錯情況二:法子設置調大了客戶端參數 hbase.client.keyvalue.maxsize,但沒有調大服務端參數 hbase.server.keyvalue.maxsize,且實際插入的 keyvalue 小于該客戶端參數,男女无遮挡猛进猛出免费视频但大于該服務端參數:

報錯情況二,某次作業日记:

Exception in thread "main"org.apache.hadoop.hbase.DoNotRetryIOException:  org.apache.hadoop.hbase.DoNotRetryIOException: Cell with size 25000046 exceeds limit of 10485760 bytes  at org.apache.hadoop.hbase.regionserver.RSRpcServices.checkCellSizeLimit(RSRpcServices.java:944)     at org.apache.hadoop.hbase.regionserver.RSRpcServices.mutate(RSRpcServices.java:2792)     at org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:42000)     at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:413)     at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:130)     at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:324)     at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:304) 

報錯情況二,某次報錯截圖:

05 該線上 Hbase 問題的解決决策

知道了問題原因,其實解決要领也就呼之欲出了,在確認要插入的業務數據沒有異常,確實需要調大 keyvalue 抑制的閾值時,大體總結下,有以下解決辦法:

要领一:修改确立文献 hbase-site.xml, 調大客戶端參數 hbase.client.keyvalue.maxsize 的值; 要领二:淌若使用了 HBASE JAVA API, 不错修改代碼使用 configuration 對象修改此客戶端參數的默認确立:Configuration conf = HBaseConfiguration.create(); conf.set("hbase.client.keyvalue.maxsize","20971520"); 要领三:淌若使用了 HIVE,不错在客戶端覆蓋該客戶端參數:set hbase.client.keyvalue.maxsize=0; (hive sql中) 說明:一般該客戶端參數和服務端參數,默認值應該确立一樣;當蜕变服務端參數時,需要重啟服務端智商成效;當蜕变客戶端參數時,不同客戶端設置的值不错不同,且不需要重啟服務端; 在CDH中确立蜕变截圖如下:

06 該線上 Hbase 問題的技術配景 Hbase 內部是通過 KeyValue 結構來存儲表數據的,某個 KeyValue 對應的是 Hbase 大寬表中的某行的某列,每個 KeyVlue 內部內容包含:rowKey+CF(ColumnFamily)+CQ(Column qualifier)+Timestamp+Value; hbase 在進行 PUT 操作的時候,會逐個檢查要插入的每個列 (keyvalue cell) 的大小,當其大小大于 maxKeyValueSize 時,就會拋出異常,拒絕寫入; maxKeyValueSize 大小相關的參數,在hbase-1.4 已往的版块中,(包括hbase 1.2.0-cdh5.14.2 和 hbase 1.2.0-cdh5.16.2),只须一個客戶端參數 hbase.client.keyvalue.maxsize; maxKeyValueSize 大小相關的參數,在 hbase-1.4 及以后版块中,除了該客戶端參數 hbase.client.keyvalue.maxsize,還有一個服務端參數 hbase.server.keyvalue.maxsize; Hbase 抑制每個 KeyValue 大小的原因,主要在于: Hbase 需要在 hdfs 存儲引擎(基于分磁盤)之上提供對數據實時讀寫的复古,因此 Hbase 在內部數據讀寫時使用了 LSM 數據結構 (Log-Structured-Merge Tree),這背后触及到了大批對內存的使用(讀數據時使用 BlockCache,寫數據時使用 memStore),也触及到了內存數據的異步 flush 和 hfile 文献的異步 compaction;(當然為了容錯,又触及到了 wal Hlog); 因為触及到基于內存提供對數據讀寫的复古,是以需要抑制使用的內存的總大小,由于內存 BlockCache 中緩存的數據是以Block 為單位的,而Block內部存儲的是一個個 KeyValue, 是以從細節來講也需要抑制每個 KeyValue的大小; 這里的 Block 是 Hbase的倡导,不是 HDFS Block; (Hbase 每個 Block 的默認大小是 64KB, HDFS 每個BLOCK的默認大小一般是 128MB); 該客戶端參數 hbase.client.keyvalue.maxsize,和服務端參數hbase.server.keyvalue.maxsize,集群級別的默認确立推薦保持一致,且不推薦在集群級別确立這兩個參數為0或更小(即禁用大小檢查),因為此時可能會形成某個cell 存很大的數據比如 1G,此時集群性能就會大打扣头; 服務端參數只可在服務端進行确立,且确立后要重啟服務端的 hbase, 其做用是 “This is a safety setting to protect the server from OOM situations.”; 客戶端參數不错在服務端進行全局默認确立,也不错在客戶端進行定制确立,不同客戶端設置的值不错不同,但不行大于服務端的值,且客戶端确立后不需要重啟服務端,其含義是:一個KeyValue實例的最大size(一個KeyValue在io時是不行進一步分割的); 客戶端參數,具體需要設置為多大,需要根據業務允許的最大keyValue是若干來進行确立,默認是10M,一般是以默認值10M為基礎,淌若有客戶碰到以上報錯,且實際的KEYVALUE也不是業務臟數據,就調大1倍到20MB望望; 在通過hive外在使用 HBaseStorageHandler 向 HBASE 寫數據時,不错平直在beeline中蜕变确立客戶端參數 (set hbase.client.keyvalue.maxsize=10485760),不需要重啟hbase服務端; 在磋议某個開源組件的某個類或确立文献,在不同版块的變化歷史時,不错通過 git clone 在土产货克隆創建 git repository,然后在土产货 IDEA 中通過使用号召 git->show history 對比不同版块中類或确立文献的,進而確認到 JIRA 記錄號,并在JIRA中確認相關細節; 更多關于hbase數據存儲結構的細節:

 

hbase 中的數據,不错有多個columnFamily, 每個 columnFamily 內部不错有多個column; 每個 ColumnsFamily 落地到hdfs上的文献是 hfile/storeFile, storeFile 是由 data block組成的(block 是IO和壓縮的基本單位,默認64KB);(Within an HFile, HBase cells are stored in data blocks as a sequence of KeyValues;KeyValue instances are aggregated into blocks, which are indexed and Indexes also have to be stored; Blocksize is configurable on a per-ColumnFamily basis); 每個 block 內部存儲了多個columns,每個column都是以 keyvalue 的姿首存儲的,每個keyvalue的大小受hbase.clent.keyvalue.maxsize/hbase.server.keyvalue.maxsize抑制的; compression and DATA BLOCK ENCODING doesn't help with the cell size check, as compress and data block encoding happens when flush memstore to hfile and compaction of hfile; HBase supports several different compression algorithms which can be enabled on a ColumnFamily. Data block encoding attempts to limit duplication of information in keys, taking advantage of some of the fundamental designs and patterns of HBase, such as sorted row keys and the schema of a given table. Compressors reduce the size of large, opaque byte arrays in cells, and can significantly reduce the storage space needed to store uncompressed data.

 





Powered by 亚洲国产精品无码第一区 @2013-2022 RSS地图 HTML地图