本文主要為您介紹如何使用Hive或者HadoopMR訪問Tablestore中的表。
資料準備
在Tablestore中準備一張資料表pet,name是唯一的一列主鍵,資料樣本請參見下表。
说明 表中空白部分無需寫入,因為Tablestore是schema-free的儲存結構,沒有值也無需寫入NULL。
name | owner | species | sex | birth | death |
---|---|---|---|---|---|
Fluffy | Harold | cat | f | 1993-02-04 | |
Claws | Gwen | cat | m | 1994-03-17 | |
Buffy | Harold | dog | f | 1989-05-13 | |
Fang | Benny | dog | m | 1990-08-27 | |
Bowser | Diane | dog | m | 1979-08-31 | 1995-07-29 |
Chirpy | Gwen | bird | f | 1998-09-11 | |
Whistler | Gwen | bird | 1997-12-09 | ||
Slim | Benny | snake | m | 1996-04-29 | |
Puffball | Diane | hamster | f | 1999-03-30 |
Hive訪問樣本
- HADOOP_HOME及HADOOP_CLASSPATH可以添加到/etc/profile中,樣本如下:
export HADOOP_HOME=${您的Hadoop安裝目錄} export HADOOP_CLASSPATH=emr-tablestore-1.4.2.jar:tablestore-4.3.1-jar-with-dependencies.jar:joda-time-2.9.4.jar
- 執行bin/hive命令進入hive後,建立外表。樣本如下:
CREATE EXTERNAL TABLE pet (name STRING, owner STRING, species STRING, sex STRING, birth STRING, death STRING) STORED BY 'com.aliyun.openservices.tablestore.hive.TableStoreStorageHandler' WITH SERDEPROPERTIES( "tablestore.columns.mapping"="name,owner,species,sex,birth,death") TBLPROPERTIES ( "tablestore.endpoint"="YourEndpoint", "tablestore.access_key_id"="YourAccessKeyId", "tablestore.access_key_secret"="YourAccessKeySecret", "tablestore.table.name"="pet");
具體配置項說明請參見下表。配置項 說明 WITH SERDEPROPERTIES 欄位對應配置,包括tablestore.columns.mapping選項配置。 在預設的情況下,外表的欄位名即為Tablestore上表的列名(主鍵列名或屬性列名)。但有時外表的欄位名和表上列名並不一致(例如處理大小寫或字元集相關的問題),此時需要指定tablestore.columns.mapping。該參數為一個英文逗號分隔的字串,每個分隔之間不能添加空格,每一項都是表中列名,順序與外表欄位保持一致。说明 Tablestore的列名支援空白字元,所以空白也會被認為是表中列名的一部分。TBLPROPERTIES 表的屬性配置。包括如下選項: - tablestore.endpoint(必選):訪問Tablestore的服務地址,您可以在Tablestore控制台上查看執行個體的Endpoint資訊。關於服務地址的更多資訊,請參見服務地址。
- tablestore.instance(可選):Tablestore的執行個體名稱。如果不填寫,則為tablestore.endpoint的第一段。關於執行個體的更多資訊,請參見執行個體。
- tablestore.access_key_id(必選):阿里雲帳號或者RAM使用者的AccessKey ID。更多資訊,請參見擷取AccessKey。
當要使用STS服務臨時訪問資源時,請設定此參數為臨時訪問憑證的AccessKey ID。
- tablestore.access_key_secret(必選):阿里雲帳號或者RAM使用者的AccessKey Secret。更多資訊,請參見擷取AccessKey。
當要使用STS服務臨時訪問資源時,請設定此參數為臨時訪問憑證的AccessKey Secret。
- tablestore.sts_token(可選):臨時訪問憑證的安全性權杖。當要使用STS服務臨時訪問資源時,才需要設定此參數。更多資訊,請參見配置臨時使用者權限。
- tablestore.table.name(必選):Tablestore中對應的表名。
- 查詢表中資料。
- 執行SELECT * FROM pet;命令查詢表中所有行資料。
返回結果樣本如下:
Bowser Diane dog m 1979-08-31 1995-07-29 Buffy Harold dog f 1989-05-13 NULL Chirpy Gwen bird f 1998-09-11 NULL Claws Gwen cat m 1994-03-17 NULL Fang Benny dog m 1990-08-27 NULL Fluffy Harold cat f 1993-02-04 NULL Puffball Diane hamster f 1999-03-30 NULL Slim Benny snake m 1996-04-29 NULL Whistler Gwen bird NULL 1997-12-09 NULL Time taken: 5.045 seconds, Fetched 9 row(s)
- 執行SELECT * FROM pet WHERE birth > "1995-01-01";命令查詢表中birth列值大於1995-01-01的行資料。
返回結果樣本如下:
Chirpy Gwen bird f 1998-09-11 NULL Puffball Diane hamster f 1999-03-30 NULL Slim Benny snake m 1996-04-29 NULL Whistler Gwen bird NULL 1997-12-09 NULL Time taken: 1.41 seconds, Fetched 4 row(s)
返回結果樣本如下:Bowser Diane dog m 1979-08-31 1995-07-29 Buffy Harold dog f 1989-05-13 NULL Chirpy Gwen bird f 1998-09-11 NULL Claws Gwen cat m 1994-03-17 NULL Fang Benny dog m 1990-08-27 NULL Fluffy Harold cat f 1993-02-04 NULL Puffball Diane hamster f 1999-03-30 NULL Slim Benny snake m 1996-04-29 NULL Whistler Gwen bird NULL 1997-12-09 NULL Time taken: 5.045 seconds, Fetched 9 row(s) hive> SELECT * FROM pet WHERE birth > "1995-01-01"; Chirpy Gwen bird f 1998-09-11 NULL Puffball Diane hamster f 1999-03-30 NULL Slim Benny snake m 1996-04-29 NULL Whistler Gwen bird NULL 1997-12-09 NULL Time taken: 1.41 seconds, Fetched 4 row(s)
- 執行SELECT * FROM pet;命令查詢表中所有行資料。
HadoopMR訪問樣本
以下樣本介紹如何使用HadoopMR程式統計資料表pet的行數。
- 構建Mappers和Reducers
public class RowCounter { public static class RowCounterMapper extends Mapper<PrimaryKeyWritable, RowWritable, Text, LongWritable> { private final static Text agg = new Text("TOTAL"); private final static LongWritable one = new LongWritable(1); @Override public void map( PrimaryKeyWritable key, RowWritable value, Context context) throws IOException, InterruptedException { context.write(agg, one); } } public static class IntSumReducer extends Reducer<Text,LongWritable,Text,LongWritable> { @Override public void reduce( Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException { long sum = 0; for (LongWritable val : values) { sum += val.get(); } context.write(key, new LongWritable(sum)); } } }
資料來源每從Tablestore上讀出一行,都會調用一次mapper的map()。PrimaryKeyWritable和RowWritable兩個參數分別對應這行的主鍵以及該行的內容。您可以通過調用PrimaryKeyWritable.getPrimaryKey()和RowWritable.getRow()取得Tablestore Java SDK定義的主鍵對象及行對象。
- 配置Tablestore作為mapper的資料來源。
private static RangeRowQueryCriteria fetchCriteria() { RangeRowQueryCriteria res = new RangeRowQueryCriteria("YourTableName"); res.setMaxVersions(1); List<PrimaryKeyColumn> lower = new ArrayList<PrimaryKeyColumn>(); List<PrimaryKeyColumn> upper = new ArrayList<PrimaryKeyColumn>(); lower.add(new PrimaryKeyColumn("YourPkeyName", PrimaryKeyValue.INF_MIN)); upper.add(new PrimaryKeyColumn("YourPkeyName", PrimaryKeyValue.INF_MAX)); res.setInclusiveStartPrimaryKey(new PrimaryKey(lower)); res.setExclusiveEndPrimaryKey(new PrimaryKey(upper)); return res; } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "row count"); job.addFileToClassPath(new Path("hadoop-connector.jar")); job.setJarByClass(RowCounter.class); job.setMapperClass(RowCounterMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); job.setInputFormatClass(TableStoreInputFormat.class); TableStoreInputFormat.setEndpoint(job, "https://YourInstance.Region.ots.aliyuncs.com/"); TableStoreInputFormat.setCredential(job, "YourAccessKeyId", "YourAccessKeySecret"); TableStoreInputFormat.addCriteria(job, fetchCriteria()); FileOutputFormat.setOutputPath(job, new Path("output")); System.exit(job.waitForCompletion(true) ? 0 : 1); }
樣本中使用job.setInputFormatClass(TableStoreInputFormat.class)將Tablestore設定為資料來源,除此之外,還需要:
- 把hadoop-connector.jar部署到叢集上並添加到classpath中。路徑為addFileToClassPath()指定hadoop-connector.jar的本地路徑。代碼中假定hadoop-connector.jar在當前路徑。
- 訪問Tablestore需要指定入口和身份。通過TableStoreInputFormat.setEndpoint()和TableStoreInputFormat.setCredential()設定訪問Tablestore需要指定的Endpoint和AccessKey資訊。
- 指定一張表用來計數。
说明
- 每調用一次addCriteria()可以在資料來源裡添加一個Java SDK定義的RangeRowQueryCriteria對象。可以多次調用addCriteria()。RangeRowQueryCriteria對象與Tablestore Java SDK GetRange介面所用的RangeRowQueryCriteria對象具有相同的限制條件。
- 使用RangeRowQueryCriteria的setFilter()和addColumnsToGet()可以在Tablestore的伺服器端過濾掉不必要的行和列,減少訪問資料的大小,降低成本,提高效能。
- 通過添加對應多張表的多個RangeRowQueryCriteria,可以實現多表的union。
- 通過添加同一張表的多個RangeRowQueryCriteria,可以做到更均勻的切分。TableStore-Hadoop Connector會根據一些策略將使用者傳入的範圍切細。
程式運行樣本
- 設定HADOOP_CLASSPATH。
HADOOP_CLASSPATH=hadoop-connector.jar bin/hadoop jar row-counter.jar
- 執行find output -type f命令尋找output目錄下的所有檔案。
返回結果樣本如下:
output/_SUCCESS output/part-r-00000 output/._SUCCESS.crc output/.part-r-00000.crc
- 執行cat out/part-r-00000命令統計運行結果中的行數。
TOTAL 9
類型轉換說明
Tablestore支援的資料類型與Hive或者Spark支援的資料類型不完全相同。
下表列出了從Tablestore的資料類型(行)轉換到Hive或者Spark資料類型(列)的支援情況。
類型轉換 | TINYINT | SMALLINT | INT | BIGINT | FLOAT | DOUBLE | BOOLEAN | STRING | BINARY |
---|---|---|---|---|---|---|---|---|---|
INTEGER | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援 | 支援,損失精度 | 支援,損失精度 | 不支援 | 不支援 | 不支援 |
DOUBLE | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援 | 不支援 | 不支援 | 不支援 |
BOOLEAN | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 支援 | 不支援 | 不支援 |
STRING | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 支援 | 不支援 |
BINARY | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 支援 |