本文主要為您介紹如何使用Hive或者HadoopMR訪問Table Store中的表。
資料準備
在Table Store中準備一張資料表pet,name是唯一的一列主鍵,資料樣本請參見下表。
表中空白部分無需寫入,因為Table Store是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選項配置。
在預設情況下,外表的欄位名即為Table Store上表的列名(主鍵列名或屬性列名)。但有時外表的欄位名和表上列名並不一致(例如處理大小寫或字元集相關的問題),此時需要指定tablestore.columns.mapping。該參數為一個英文逗號分隔的字串,每個分隔之間不能添加空格,每一項都是表中列名,順序與外表欄位保持一致。
說明Table Store的列名支援空白字元,所以空白也會被認為是表中列名的一部分。
TBLPROPERTIES
表的屬性配置。包括如下選項:
tablestore.endpoint(必選):訪問Table Store的服務地址,您可以在Table Store控制台上查看執行個體的Endpoint資訊。關於服務地址的更多資訊,請參見服務地址。
tablestore.instance(可選):Table Store的執行個體名稱。如果不填寫,則為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服務臨時訪問資源時,才需要設定此參數。更多資訊,請參見通過RAM Policy為RAM使用者授權。
tablestore.table.name(必選):Table Store中對應的表名。
查詢表中資料。
執行
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)
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)); } } }
資料來源每從Table Store上讀出一行,都會調用一次mapper的map()。PrimaryKeyWritable和RowWritable兩個參數分別對應這行的主鍵以及該行的內容。您可以通過調用PrimaryKeyWritable.getPrimaryKey()和RowWritable.getRow()取得Table StoreJava SDK定義的主鍵對象及行對象。
配置Table Store作為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)將Table Store設定為資料來源,除此之外,還需要:
把hadoop-connector.jar部署到叢集上並添加到classpath中。路徑為addFileToClassPath()指定hadoop-connector.jar的本地路徑。代碼中假定hadoop-connector.jar在當前路徑。
訪問Table Store需要指定入口和身份。通過TableStoreInputFormat.setEndpoint()和TableStoreInputFormat.setCredential()設定訪問Table Store需要指定的Endpoint和AccessKey資訊。
指定一張表用來計數。
說明每調用一次addCriteria()可以在資料來源裡添加一個Java SDK定義的RangeRowQueryCriteria對象。可以多次調用addCriteria()。RangeRowQueryCriteria對象與Table StoreJava SDK GetRange介面所用的RangeRowQueryCriteria對象具有相同的限制條件。
使用RangeRowQueryCriteria的setFilter()和addColumnsToGet()可以在Table Store的伺服器端過濾掉不必要的行和列,減少訪問資料的大小,降低成本,提高效能。
通過添加對應多張表的多個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 output/part-r-00000
命令統計運行結果中的行數。TOTAL 9
類型轉換說明
Table Store支援的資料類型與Hive或者Spark支援的資料類型不完全相同。
下表列出了從Table Store的資料類型(行)轉換到Hive或Spark資料類型(列)的支援情況。
類型轉換 | TINYINT | SMALLINT | INT | BIGINT | FLOAT | DOUBLE | BOOLEAN | STRING | BINARY |
INTEGER | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援 | 支援,損失精度 | 支援,損失精度 | 不支援 | 不支援 | 不支援 |
DOUBLE | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援,損失精度 | 支援 | 不支援 | 不支援 | 不支援 |
BOOLEAN | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 支援 | 不支援 | 不支援 |
STRING | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 支援 | 不支援 |
BINARY | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 不支援 | 支援 |