(实验)Key Value Store客户端API

Slack Docker Pulls GitHub edit source

综述

Alluxio除了提供Filesystem API 让应用程序来读写和管理文件,还在文件系统 之上提供了键值(key-value)存储。 就像Alluxio文件系统中的文件一样,键值存储的语义是write-once。

  • 用户可以创建一个键值存储库并且把键值对放入其中。键值对放入存储后是不可变的。
  • 键值存储库完整保存后,用户可以打开并使用该键值存储库。

键值存储库可以用AlluxioURI来表示路径,比如alluxio://192.168.1.200:19998/path/my-kvstore, 表示master地址为192.168.1.200,RPC端口为19998,键值存储库路径为/path/my-kvstore。 根据总容量和用户指定的数据块大小,单个键值存储库可能有一个以上的分区,分区是由Alluxio内部来管理,对用户透明。

键值存储库配置参数

Alluxio默认配置是禁用键值存储库的,可以通过配置alluxio.keyvalue.enabled为true来启用 (see configuration parameters)

以下是键值存储库的配置参数:

属性名默认值意义
alluxio.keyvalue.enabledfalse是否开启key-value键值存储服务
alluxio.keyvalue.partition.size.bytes.max512MB每个分区的大小上限

快速测试

当启动Alluxio键值存储库后,可以运行./bin/alluxio runKVTest来快速测试键值存储库是否正常运行,如果运行 正常,应该在最后的输出结果中看到Passed the test!

通过Java应用程序来访问键值存储库

获取一个键值存储库的客户端

要想用Java代码获取一个Alluxio键值存储系统客户端实例,可以使用:

  1. KeyValueSystem kvs = KeyValueSystem.Factory.create();

创建一个新的键值存储库

可以通过调用KeyValueSystem#createStore(AlluxioURI)来创建一个新的键值存储库。将返回一个writer用于后续 加入键值对。可以参照下面的例子:

  1. KeyValueStoreWriter writer = kvs.createStore(new AlluxioURI("alluxio://192.168.1.200:19998/path/my-kvstore"));
  2. // Insert key-value pair ("100", "foo")
  3. writer.put("100", "foo");
  4. // Insert key-value pair ("200", "bar")
  5. writer.put("200", "bar");
  6. // Close and complete the store
  7. writer.close();

需要注意的是,

  • 在writer关闭之前,该键值存储库是不完整并且不可用的;
  • 在某些情况下,该键值存储库的空间会大于一个分区的最大容许容量。在这种情况下,writer会把键值对存于多个分区, 分区的切换对于用户是透明的。
  • 写入的键应该是排了序的并且没有重复的键值。

从存储库中读取值

可以通过调用KeyValueSystem#openStore(AlluxioURI)来读取一个完整的键值存储库。将返回一个reader用于后续 基于键的值读取。可以参照下面的例子:

  1. KeyValueStoreReader reader = kvs.openStore(new AlluxioURI("alluxio://192.168.1.200:19998/path/kvstore/"));
  2. // Return "foo"
  3. reader.get("100");
  4. // Return null as no value associated with "300"
  5. reader.get("300");
  6. // Close the reader on the store
  7. reader.close();

通过迭代器遍历存储中的键值对

可以参照下面的例子:

  1. KeyValueStoreReader reader = kvs.openStore(new AlluxioURI("alluxio://192.168.1.200:19998/path/kvstore/"));
  2. KeyValueIterator iterator = reader.iterator();
  3. while (iterator.hasNext()) {
  4. KeyValuePair pair = iterator.next();
  5. ByteBuffer key = pair.getkKey();
  6. ByteBuffer value = pair.getValue();
  7. }
  8. // Close the reader on the store
  9. reader.close()

样例

从代码库中的样例 可以了解更多。

在Hadoop MapReduce内访问键值存储库

MapReduce InputFormat

Alluxio提供了一种InputFormat的实现使得Hadoop MapReduce程序可以访问键值存储库。它使用一个key-value URI作为参数,把键值对放入键值存储库内。

  1. conf.setInputFormat(KeyValueInputFormat.class);
  2. FileInputFormat.setInputPaths(conf, new Path("alluxio://192.168.1.200:19998/input-store"));

MapReduce OutputFormat

Alluxio同时提供了一种OutputFormat的实现使得Hadoop MapReduce程序可以创建一个键值存储库。它使用一个 key-value URI作为参数把键值对放入键值存储库内。

  1. conf.setOutputKeyClass(BytesWritable.class);
  2. conf.setOutputValueClass(BytesWritable.class);
  3. conf.setOutputFormat(KeyValueOutputFormat.class);
  4. FileOutputFormat.setOutputPath(conf, new Path("alluxio://192.168.1.200:19998/output-store"));

样例

从代码库中的样例 可以了解更多。

如果你已经将HDFS配置为Alluxio的底层存储, 并且已经启用了键值存储, 那么可以按照如下方式运行上面的样例:

  1. export HADOOP_CLASSPATH=${ALLUXIO_INSTALLATION_DIRECTORY}/assembly/target/alluxio-assemblies-${ALLUXIO_VERSION}-jar-with-dependencies.jar
  2. ${HADOOP_INSTALLATION_DIRECTORY}/bin/hadoop jar \
  3. ${ALLUXIO_INSTALLATION_DIRECTORY}/examples/target/alluxio-examples-${ALLUXIO_VERSION}.jar \
  4. alluxio.examples.keyvalue.hadoop.CloneStoreMapReduce alluxio://${ALLUXIO_MASTER}:${PORT}/${INPUT_KEY_VALUE_STORE_PATH} alluxio://${ALLUXIO_MASTER}:${PORT}/${OUTPUT_KEY_VALUE_STORE_PATH} \
  5. -libjars=${ALLUXIO_INSTALLATION_DIRECTORY}/assembly/target/alluxio-assemblies-${ALLUXIO_VERSION}-jar-with-dependencies.jar