blob: 7dacc34de926cf24654285c14e5d83925b7557bd [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pegasus | Java Client</title>
<link rel="stylesheet" href="/zh/assets/css/app.css">
<link rel="shortcut icon" href="/zh/assets/images/favicon.ico">
<link rel="stylesheet" href="/zh/assets/css/utilities.min.css">
<link rel="stylesheet" href="/zh/assets/css/docsearch.v3.css">
<script src="/assets/js/jquery.min.js"></script>
<script src="/assets/js/all.min.js"></script>
<script src="/assets/js/docsearch.v3.js"></script>
<!-- Begin Jekyll SEO tag v2.8.0 -->
<title>Java Client | Pegasus</title>
<meta name="generator" content="Jekyll v4.3.2" />
<meta property="og:title" content="Java Client" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="获取Java客户端" />
<meta property="og:description" content="获取Java客户端" />
<meta property="og:site_name" content="Pegasus" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-11-23T14:57:08+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Java Client" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","dateModified":"2023-11-23T14:57:08+00:00","datePublished":"2023-11-23T14:57:08+00:00","description":"获取Java客户端","headline":"Java Client","mainEntityOfPage":{"@type":"WebPage","@id":"/clients/java-client"},"url":"/clients/java-client"}</script>
<!-- End Jekyll SEO tag -->
</head>
<body>
<div class="dashboard is-full-height">
<!-- left panel -->
<div class="dashboard-panel is-medium is-hidden-mobile pl-0">
<div class="dashboard-panel-header has-text-centered">
<a href="/zh/">
<img src="/assets/images/pegasus-logo-inv.png" style="width: 80%;">
</a>
</div>
<div class="dashboard-panel-main is-scrollable pl-6">
<aside class="menu">
<p class="menu-label">Pegasus产品文档</p>
<ul class="menu-list">
<li>
<a href="/zh/docs/downloads"
class="">
下载
</a>
</li>
</ul>
<p class="menu-label">编译构建</p>
<ul class="menu-list">
<li>
<a href="/zh/docs/build/compile-by-docker"
class="">
使用Docker完成编译(推荐)
</a>
</li>
<li>
<a href="/zh/docs/build/compile-from-source"
class="">
从源码编译
</a>
</li>
</ul>
<p class="menu-label">客户端库</p>
<ul class="menu-list">
<li>
<a href="/zh/clients/java-client"
class="is-active">
Java客户端
</a>
</li>
<li>
<a href="/zh/clients/cpp-client"
class="">
C++客户端
</a>
</li>
<li>
<a href="https://github.com/apache/incubator-pegasus/tree/master/go-client"
class="">
Golang客户端
</a>
</li>
<li>
<a href="/zh/clients/python-client"
class="">
Python客户端
</a>
</li>
<li>
<a href="/zh/clients/node-client"
class="">
NodeJS客户端
</a>
</li>
<li>
<a href="/zh/clients/scala-client"
class="">
Scala客户端
</a>
</li>
</ul>
<p class="menu-label">生态工具</p>
<ul class="menu-list">
<li>
<a href="/zh/docs/tools/shell"
class="">
Pegasus Shell 工具
</a>
</li>
<li>
<a href="https://github.com/pegasus-kv/admin-cli"
class="">
集群管理命令行
</a>
</li>
<li>
<a href="https://github.com/pegasus-kv/pegic"
class="">
数据访问命令行
</a>
</li>
</ul>
<p class="menu-label">用户接口</p>
<ul class="menu-list">
<li>
<a href="/zh/api/ttl"
class="">
TTL
</a>
</li>
<li>
<a href="/zh/api/single-atomic"
class="">
单行原子操作
</a>
</li>
<li>
<a href="/zh/api/redis"
class="">
Redis适配
</a>
</li>
<li>
<a href="/zh/api/geo"
class="">
GEO支持
</a>
</li>
<li>
<a href="/zh/api/http"
class="">
HTTP接口
</a>
</li>
</ul>
<p class="menu-label">高效运维</p>
<ul class="menu-list">
<li>
<a href="/zh/administration/deployment"
class="">
集群部署
</a>
</li>
<li>
<a href="/zh/administration/config"
class="">
配置说明
</a>
</li>
<li>
<a href="/zh/administration/rebalance"
class="">
负载均衡
</a>
</li>
<li>
<a href="/zh/administration/monitoring"
class="">
可视化监控
</a>
</li>
<li>
<a href="/zh/administration/rolling-update"
class="">
集群升级
</a>
</li>
<li>
<a href="/zh/administration/scale-in-out"
class="">
集群扩容缩容
</a>
</li>
<li>
<a href="/zh/administration/resource-management"
class="">
资源管理
</a>
</li>
<li>
<a href="/zh/administration/cold-backup"
class="">
冷备份
</a>
</li>
<li>
<a href="/zh/administration/meta-recovery"
class="">
元数据恢复
</a>
</li>
<li>
<a href="/zh/administration/replica-recovery"
class="">
Replica数据恢复
</a>
</li>
<li>
<a href="/zh/administration/zk-migration"
class="">
Zookeeper迁移
</a>
</li>
<li>
<a href="/zh/administration/table-migration"
class="">
Table迁移
</a>
</li>
<li>
<a href="/zh/administration/table-soft-delete"
class="">
Table软删除
</a>
</li>
<li>
<a href="/zh/administration/table-env"
class="">
Table环境变量
</a>
</li>
<li>
<a href="/zh/administration/remote-commands"
class="">
远程命令
</a>
</li>
<li>
<a href="/zh/administration/partition-split"
class="">
Partition-Split
</a>
</li>
<li>
<a href="/zh/administration/duplication"
class="">
跨机房同步
</a>
</li>
<li>
<a href="/zh/administration/compression"
class="">
数据压缩
</a>
</li>
<li>
<a href="/zh/administration/throttling"
class="">
流量控制
</a>
</li>
<li>
<a href="/zh/administration/experiences"
class="">
运维经验
</a>
</li>
<li>
<a href="/zh/administration/manual-compact"
class="">
Manual Compact功能
</a>
</li>
<li>
<a href="/zh/administration/usage-scenario"
class="">
Usage Scenario功能
</a>
</li>
<li>
<a href="/zh/administration/bad-disk"
class="">
坏盘检修
</a>
</li>
<li>
<a href="/zh/administration/whitelist"
class="">
白名单
</a>
</li>
<li>
<a href="/zh/administration/backup-request"
class="">
Backup Request
</a>
</li>
<li>
<a href="/zh/administration/hotspot-detection"
class="">
热点检测
</a>
</li>
</ul>
</aside>
</div>
</div>
<!-- main section -->
<div class="dashboard-main is-scrollable">
<nav class="navbar is-hidden-desktop">
<div class="navbar-brand">
<a href="/zh/" class="navbar-item">
<!-- Pegasus Icon -->
<img src="/assets/images/pegasus-square.png">
</a>
<div class="navbar-item">
<!--A simple language switch button that only supports zh and en.-->
<!--IF its language is zh, then switches to en.-->
<!--If you don't want a url to be relativized, you can add a space explicitly into the href to
prevents a url from being relativized by polyglot.-->
<a class="button is-light is-outlined is-inverted" href=" /clients/java-client"><strong>En</strong></a>
</div>
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navMenu">
<!-- Appears in mobile mode only -->
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div class="navbar-menu" id="navMenu">
<div class="navbar-end">
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
Pegasus产品文档
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/docs/downloads"
class="navbar-item ">
下载
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
编译构建
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/docs/build/compile-by-docker"
class="navbar-item ">
使用Docker完成编译(推荐)
</a>
<a href="/zh/docs/build/compile-from-source"
class="navbar-item ">
从源码编译
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
客户端库
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/clients/java-client"
class="navbar-item is-active">
Java客户端
</a>
<a href="/zh/clients/cpp-client"
class="navbar-item ">
C++客户端
</a>
<a href="https://github.com/apache/incubator-pegasus/tree/master/go-client"
class="navbar-item ">
Golang客户端
</a>
<a href="/zh/clients/python-client"
class="navbar-item ">
Python客户端
</a>
<a href="/zh/clients/node-client"
class="navbar-item ">
NodeJS客户端
</a>
<a href="/zh/clients/scala-client"
class="navbar-item ">
Scala客户端
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
生态工具
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/docs/tools/shell"
class="navbar-item ">
Pegasus Shell 工具
</a>
<a href="https://github.com/pegasus-kv/admin-cli"
class="navbar-item ">
集群管理命令行
</a>
<a href="https://github.com/pegasus-kv/pegic"
class="navbar-item ">
数据访问命令行
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
用户接口
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/api/ttl"
class="navbar-item ">
TTL
</a>
<a href="/zh/api/single-atomic"
class="navbar-item ">
单行原子操作
</a>
<a href="/zh/api/redis"
class="navbar-item ">
Redis适配
</a>
<a href="/zh/api/geo"
class="navbar-item ">
GEO支持
</a>
<a href="/zh/api/http"
class="navbar-item ">
HTTP接口
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
高效运维
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/administration/deployment"
class="navbar-item ">
集群部署
</a>
<a href="/zh/administration/config"
class="navbar-item ">
配置说明
</a>
<a href="/zh/administration/rebalance"
class="navbar-item ">
负载均衡
</a>
<a href="/zh/administration/monitoring"
class="navbar-item ">
可视化监控
</a>
<a href="/zh/administration/rolling-update"
class="navbar-item ">
集群升级
</a>
<a href="/zh/administration/scale-in-out"
class="navbar-item ">
集群扩容缩容
</a>
<a href="/zh/administration/resource-management"
class="navbar-item ">
资源管理
</a>
<a href="/zh/administration/cold-backup"
class="navbar-item ">
冷备份
</a>
<a href="/zh/administration/meta-recovery"
class="navbar-item ">
元数据恢复
</a>
<a href="/zh/administration/replica-recovery"
class="navbar-item ">
Replica数据恢复
</a>
<a href="/zh/administration/zk-migration"
class="navbar-item ">
Zookeeper迁移
</a>
<a href="/zh/administration/table-migration"
class="navbar-item ">
Table迁移
</a>
<a href="/zh/administration/table-soft-delete"
class="navbar-item ">
Table软删除
</a>
<a href="/zh/administration/table-env"
class="navbar-item ">
Table环境变量
</a>
<a href="/zh/administration/remote-commands"
class="navbar-item ">
远程命令
</a>
<a href="/zh/administration/partition-split"
class="navbar-item ">
Partition-Split
</a>
<a href="/zh/administration/duplication"
class="navbar-item ">
跨机房同步
</a>
<a href="/zh/administration/compression"
class="navbar-item ">
数据压缩
</a>
<a href="/zh/administration/throttling"
class="navbar-item ">
流量控制
</a>
<a href="/zh/administration/experiences"
class="navbar-item ">
运维经验
</a>
<a href="/zh/administration/manual-compact"
class="navbar-item ">
Manual Compact功能
</a>
<a href="/zh/administration/usage-scenario"
class="navbar-item ">
Usage Scenario功能
</a>
<a href="/zh/administration/bad-disk"
class="navbar-item ">
坏盘检修
</a>
<a href="/zh/administration/whitelist"
class="navbar-item ">
白名单
</a>
<a href="/zh/administration/backup-request"
class="navbar-item ">
Backup Request
</a>
<a href="/zh/administration/hotspot-detection"
class="navbar-item ">
热点检测
</a>
</div>
</div>
</div>
</div>
</nav>
<nav class="navbar is-hidden-mobile">
<div class="navbar-start w-full">
<div class="navbar-item pl-0 w-full">
<!--TODO(wutao): Given the limitation of docsearch that couldn't handle multiple input,
I make searchbox only shown in desktop. Fix this issue when docsearch.js v3 released.
Related issue: https://github.com/algolia/docsearch/issues/230-->
<div id="docsearch"></div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<!--A simple language switch button that only supports zh and en.-->
<!--IF its language is zh, then switches to en.-->
<!--If you don't want a url to be relativized, you can add a space explicitly into the href to
prevents a url from being relativized by polyglot.-->
<a class="button is-light is-outlined is-inverted" href=" /clients/java-client"><strong>En</strong></a>
</div>
</div>
</nav>
<section class="hero is-info lg:mr-3">
<div class="hero-body">
<p class="title is-size-2 is-centered">Java客户端</p>
</div>
</section>
<section class="section" style="padding-top: 2rem;">
<div class="content">
<h1 id="获取java客户端">获取Java客户端</h1>
<p>项目地址:<a href="https://github.com/apache/incubator-pegasus/tree/master/java-client">Pegasus Java Client</a></p>
<p>下载:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/apache/incubator-pegasus.git
<span class="nb">cd </span>pegasus-java-client
</code></pre></div></div>
<p>选择所使用的版本并构建,建议使用<a href="https://github.com/xiaomi/pegasus-java-client/releases">最新的release版本</a></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git checkout v2.0.0
mvn clean package <span class="nt">-DskipTests</span>
</code></pre></div></div>
<p>安装到本地的maven repository,方便在项目中使用:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn clean <span class="nb">install</span> <span class="nt">-DskipTests</span>
</code></pre></div></div>
<p>安装完成后,通过maven配置在项目中使用:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>com.xiaomi.infra<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>pegasus-client<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>2.0.0<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>
<p><strong>注:2.0.0版本仅适用于服务端PegasusServer &gt;= 2.0, 如果服务端版本较低,请使用下面的版本</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>com.xiaomi.infra<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>pegasus-client<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>1.11.10-thrift-0.11.0-inlined<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>
<h1 id="客户端配置">客户端配置</h1>
<p>创建Java client实例需要配置相关参数,用户可以选择两种方式进行配置:文件配置方式和参数传递方式</p>
<h2 id="文件配置">文件配置</h2>
<p>Java客户端需要准备配置文件,用以确定Pegasus集群的位置,以及配置默认超时时间等。</p>
<p>配置文件一般命名为<code class="language-plaintext highlighter-rouge">pegasus.properties</code>,样例:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">meta_servers</span> <span class="p">=</span> <span class="s">127.0.0.1:34601,127.0.0.1:34602,127.0.0.1:34603</span>
<span class="py">operation_timeout</span> <span class="p">=</span> <span class="s">1000</span>
<span class="c"># 以下参数可以根据需要添加,否则以默认值即可
</span><span class="py">async_workers</span> <span class="p">=</span> <span class="s">4</span>
<span class="py">enable_perf_counter</span> <span class="p">=</span> <span class="s">true</span>
<span class="py">perf_counter_tags</span> <span class="p">=</span> <span class="s">cluster=onebox,app=unit_test</span>
<span class="py">push_counter_interval_secs</span> <span class="p">=</span> <span class="s">10</span>
<span class="py">meta_query_timeout</span> <span class="p">=</span> <span class="s">5000</span>
</code></pre></div></div>
<p>其中:</p>
<ul>
<li>meta_servers: 必选项,表示Pegasus集群的MetaServer地址列表,用于定位集群的位置。</li>
<li>operation_timeout: 可选项,表示各操作的默认超时时间,单位毫秒,默认值为1000。接口中每个操作一般都可以指定单独的超时时间,当指定为0时,使用该默认超时时间。</li>
<li>async_workers:可选项,后台工作线程数,内部实际是Netty NIO处理客户端和replica_server之间RPC的线程,默认:4</li>
<li>enable_perf_counter:可选项,是否开启性能指标监控数据,如果开启则客户端会周期性的上报监控数据,目前仅支持<a href="http://open-falcon.org/">Falcon</a>,默认:true(2.0.0以前默认为false)</li>
<li>perf_counter_tags:可选项,falcon监控数据标签,如果开启监控,建议设置易于区分不同业务的标签名字。默认:空</li>
<li>push_counter_interval_secs:可选值,falcon监控数据上报间隔,默认:10s</li>
<li>meta_query_timeout: 可选项,与MetaServer建立连接的超时时间,一般首次建立连接将需要更多的时间,用户可以根据实际场景配置该参数,以降低服务首次启动后的请求超时问题。连接默认值:5000ms(2.0.0以前没有该参数,默认等于operation_timeout)</li>
</ul>
<p>配置文件在创建Client实例的时候使用,需传入configPath参数:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">PegasusClientInterface</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">PegasusClientFactory</span><span class="o">.</span><span class="na">getSingletonClient</span><span class="o">(</span><span class="n">configPath</span><span class="o">);</span>
</code></pre></div></div>
<p>其中configPath的格式为<code class="language-plaintext highlighter-rouge">type : // path</code>,目前type支持三种类型:</p>
<ul>
<li>本地文件系统
<ul>
<li>格式:file:///path/to/config</li>
<li>样例1:file://./pegasus.properties (表示本地 ./pegasus.properties 文件)</li>
<li>样例2:file:///home/work/pegasus.properties (表示本地 /home/work/pegasus.properties 文件)</li>
</ul>
</li>
<li>Java Resource
<ul>
<li>格式:resource:///path/to/config</li>
<li>样例1:resource:///pegasus.properties</li>
<li>样例2:resource:///com/xiaomi/xxx/pegasus.properties</li>
</ul>
</li>
<li>Zookeeper
<ul>
<li>格式:zk://host1:port1,host2:port2,host3:port3/path/to/config</li>
<li>样例1:zk://127.0.0.1:2181/databases/pegasus/pegasus.properties</li>
<li>样例2:zk://127.0.0.1:2181,127.0.0.1:2182/databases/pegasus/pegasus.properties</li>
</ul>
</li>
</ul>
<h2 id="参数传递">参数传递</h2>
<p>用户可以选择构造ClientOptions实例作为创建客户端实例的参数,ClientOptions包含下列参数:</p>
<ul>
<li>metaServers:必选项,meta_servers地址,默认:127.0.0.1:34601,127.0.0.1:34602,127.0.0.1:34603</li>
<li>operationTimeout:可选项,客户端请求的超时阈值,默认:1000ms</li>
<li>asyncWorkers:可选项,后台工作线程数,内部实际是Netty NIO处理客户端和replica_server之间RPC的线程,默认:4</li>
<li>enablePerfCounter:可选项,是否开启性能指标监控数据,如果开启则客户端会周期性的上报监控数据,目前仅支持<a href="http://open-falcon.org/">Falcon</a>,默认:false</li>
<li>falconPerfCounterTags:可选项,falcon监控数据标签,如果开启监控,建议设置易于区分不同业务的标签名字。默认:空</li>
<li>falconPushInterval:可选项,falcon监控数据上报间隔,默认:10s</li>
<li>metaQueryTimeout: 可选项,与MetaServer建立连接的超时时间,一般首次建立连接将需要更多的时间,用户可以根据实际场景配置该参数,以降低服务首次启动后的请求超时问题。连接默认值:5000ms(2.0.0以前没有该参数,默认等于operation_timeout)</li>
</ul>
<p>其中ClientOptions实例提供两种创建方式,你可以使用:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ClientOptions</span> <span class="n">clientOptions</span> <span class="o">=</span> <span class="nc">ClientOptions</span><span class="o">.</span><span class="na">create</span><span class="o">()</span>
</code></pre></div></div>
<p>创建默认的ClientOptions实例。否则,可以参照下列样例创建自定义的实例:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ClientOptions</span> <span class="n">clientOptions</span> <span class="o">=</span>
<span class="nc">ClientOptions</span><span class="o">.</span><span class="na">builder</span><span class="o">()</span>
<span class="o">.</span><span class="na">metaServers</span><span class="o">(</span><span class="s">"127.0.0.1:34601,127.0.0.1:34602,127.0.0.1:34603"</span><span class="o">)</span>
<span class="o">.</span><span class="na">operationTimeout</span><span class="o">(</span><span class="nc">Duration</span><span class="o">.</span><span class="na">ofMillis</span><span class="o">(</span><span class="mi">1000</span><span class="o">))</span>
<span class="o">.</span><span class="na">asyncWorkers</span><span class="o">(</span><span class="mi">4</span><span class="o">)</span>
<span class="o">.</span><span class="na">enablePerfCounter</span><span class="o">(</span><span class="kc">false</span><span class="o">)</span>
<span class="o">.</span><span class="na">falconPerfCounterTags</span><span class="o">(</span><span class="s">""</span><span class="o">)</span>
<span class="o">.</span><span class="na">falconPushInterval</span><span class="o">(</span><span class="nc">Duration</span><span class="o">.</span><span class="na">ofSeconds</span><span class="o">(</span><span class="mi">10</span><span class="o">))</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<h1 id="接口定义">接口定义</h1>
<p>Java客户端的类都在<code class="language-plaintext highlighter-rouge">com.xiaomi.infra.pegasus.client</code>包下面,主要提供了三个类:</p>
<table>
<thead>
<tr>
<th>类名</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td>PegasusClientFactory</td>
<td>Client工厂类,用于创建Client实例</td>
</tr>
<tr>
<td>PegasusClientInterface</td>
<td>Client接口类,封装了各种<strong>同步API</strong>,也可用于创建Table实例</td>
</tr>
<tr>
<td>PegasusTableInterface</td>
<td>Table接口类,封装了存取单个Table数据的<strong>同步和异步API</strong></td>
</tr>
</tbody>
</table>
<p>用户可以选择使用Client接口(PegasusClientInterface)或者是Table接(PegasusTableInterface)存取数据,区别如下:</p>
<ul>
<li>Client接口直接在参数中指定表名,省去了打开表的动作,使用更便捷。</li>
<li>Table接口同时支持<strong>同步和异步API</strong>,而Client接口只支持<strong>同步API</strong></li>
<li>Table接口可以为每个操作设置单独的超时,而Client接口无法单独指定超时,只能使用配置文件中的默认超时。</li>
<li>Table接口在2.0.0中增加了backupRequestDelayMs参数,可以开启backup-request功能,以提高读性能,详情参见:<a href="/zh/administration/backup-request">Backup-Request</a></li>
<li>Table接口的超时更准确,而Client接口在首次读写请求时可能需要在内部初始化Table对象,所以首次读写的超时可能不太准确。</li>
<li>推荐用户首选Table接口。</li>
</ul>
<h2 id="创建client实例">创建Client实例</h2>
<p>创建Client实例有两种方式:单例和非单例。</p>
<h3 id="单例">单例</h3>
<p>如果程序中只需要访问<strong>单个集群</strong>,那么用单例是比较合适的,这样可以共享各种资源,譬如线程池、连接等。</p>
<p><strong>注意</strong>:如果在多个地方调用<code class="language-plaintext highlighter-rouge">getSingletonClient()</code>获取单例对象,需要保证传入的configPath或者ClientOptions对象是一致的,不然就会抛出异常,这样是为了保证多次调用获取到的是同一个实例。</p>
<p>调用<code class="language-plaintext highlighter-rouge">PegasusClientFactory::getSingletonClient()</code>方法获取PegasusClientInterface的单例对象:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Get the singleton client instance with default config path of "resource:///pegasus.properties".
* After used, should call PegasusClientFactory.closeSingletonClient() to release resource.
*
* @return PegasusClientInterface PegasusClientInterface.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">PegasusClientInterface</span> <span class="nf">getSingletonClient</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="cm">/**
* Get the singleton client instance with customized config path. After used, should call
* PegasusClientFactory.closeSingletonClient() to release resource.
*
* @param configPath configPath could be:
* - zookeeper path : zk://host1:port1,host2:port2,host3:port3/path/to/config
* - local file path : file:///path/to/config
* - java resource : resource:///path/to/config
*
* @return PegasusClientInterface PegasusClientInterface.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">PegasusClientInterface</span> <span class="nf">getSingletonClient</span><span class="o">(</span><span class="nc">String</span> <span class="n">configPath</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="cm">/**
* Get the singleton client instance instance with ClientOptions. After used, should call
* PegasusClientFactory.closeSingletonClient() to release resource.
*
* @param options The client option
* @return PegasusClientInterface PegasusClientInterface.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">PegasusClientInterface</span> <span class="nf">getSingletonClient</span><span class="o">(</span><span class="nc">ClientOptions</span> <span class="n">options</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>使用完毕后,记得close单例以释放资源,譬如:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">PegasusClientInterface</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">PegasusClientFactory</span><span class="o">.</span><span class="na">getSingletonClient</span><span class="o">(</span><span class="n">configPath</span><span class="o">);</span>
<span class="o">...</span> <span class="o">...</span>
<span class="nc">PegasusClientFactory</span><span class="o">.</span><span class="na">closeSingletonClient</span><span class="o">();</span>
</code></pre></div></div>
<h3 id="非单例">非单例</h3>
<p>如果在程序中需要访问多个集群,就不能用单例了。因此我们提供了创建普通实例的接口,创建时传入一个configPath或者ClientOptions对象,不同集群使用不同的configPath或者ClientOptions对象。</p>
<p><strong>注意</strong>:每个实例都拥有自己独立的资源,互不影响,因此要尽量避免重复创建实例,造成资源浪费,并且使用完后要记得调用close()释放资源。</p>
<p>调用<code class="language-plaintext highlighter-rouge">PegasusClientFactory::createClient()</code>方法,获取非单例的client实例:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Create a client instance. After used, should call client.close() to release resource.
*
* @param configPath client config path,could be:
* - zookeeper path : zk://host1:port1,host2:port2,host3:port3/path/to/config
* - local file path : file:///path/to/config
* - java resource : resource:///path/to/config
*
* @return PegasusClientInterface.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">PegasusClientInterface</span> <span class="nf">createClient</span><span class="o">(</span><span class="nc">String</span> <span class="n">configPath</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="cm">/**
* Create a client instance instance with ClientOptions. After used, should call
* client.close() to release resource.
*
* @param options The client option
* @return PegasusClientInterface.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">PegasusClientInterface</span> <span class="nf">createClient</span><span class="o">(</span><span class="nc">ClientOptions</span> <span class="n">options</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>譬如:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">PegasusClientInterface</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">PegasusClientFactory</span><span class="o">.</span><span class="na">createClient</span><span class="o">(</span><span class="n">configPath</span><span class="o">);</span>
<span class="o">...</span> <span class="o">...</span>
<span class="n">client</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
</code></pre></div></div>
<h2 id="pegasusclientinterface接口">PegasusClientInterface接口</h2>
<h3 id="get">get</h3>
<p>读单行数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Get value.
* @param tableName TableHandler name
* @param hashKey used to decide which partition to get this k-v,
* if null or length == 0, means hash key is "".
* @param sortKey all the k-v under hashKey will be sorted by sortKey,
* if null or length == 0, means sort key is "".
* @return value; null if not found
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">get</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKey。</li>
<li>返回值:如果返回null,表示key对应的数据不存在</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="batchget">batchGet</h3>
<p>读取一批数据,对get函数的批量封装。该函数并发地向server发送异步请求,并等待结果。如果有任意一个请求失败,就提前终止并抛出异常。如果抛出了异常,则values中的结果是未定义的。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch get values of different keys.
* Will terminate immediately if any error occurs.
* @param tableName table name
* @param keys hashKey and sortKey pair list.
* @param values output values; should be created by caller; if succeed, the size of values will
* be same with keys; the value of keys[i] is stored in values[i]; if the value of
* keys[i] is not found, then values[i] will be set to null.
* @throws PException throws exception if any error occurs.
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchGet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Keys。</li>
<li>传出参数:Values。该变量需由调用者创建;如果读取成功,Values[i]中存放Keys[i]对应的结果,如果value不存在则为null。</li>
</ul>
</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,只要任意一个失败都会抛出异常。</li>
</ul>
<h3 id="batchget2">batchGet2</h3>
<p>读取一批数据,对get函数的批量封装。该函数并发地向server发送异步请求,但与上面batchGet不同的是,无论请求成功还是失败,它都会等待所有请求结束。</p>
<p>用户可以根据results中的PException是否设置来判断请求成功还是失败,并可以选择只使用成功的结果。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch get values of different keys.
* Will wait for all requests done even if some error occurs.
* @param tableName table name
* @param keys hashKey and sortKey pair list.
* @param results output results; should be created by caller; after call done, the size of results will
* be same with keys; the results[i] is a Pair:
* - if Pair.left != null : means query keys[i] failed, Pair.left is the exception.
* - if Pair.left == null : means query keys[i] succeed, Pair.right is the result value.
* @return succeed count.
* @throws PException
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchGet2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Keys。</li>
<li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Keys[i]对应的结果;如果Results[i].left不为null(PException已设置),表示对Keys[i]的请求失败。</li>
</ul>
</li>
<li>返回值:请求成功的个数。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,用户可以选择只使用成功的结果。</li>
</ul>
<h3 id="multiget">multiGet</h3>
<p>读同一HashKey下的多行数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Get multiple value under the same hash key.
* @param tableName table name
* @param hashKey used to decide which partition to put this k-v,
* should not be null or empty.
* @param sortKeys all the k-v under hashKey will be sorted by sortKey,
* if null or empty, means fetch all sortKeys under the hashKey.
* @param maxFetchCount max count of k-v pairs to be fetched.
* max_fetch_count &lt;= 0 means no limit. default value is 100.
* @param maxFetchSize max size of k-v pairs to be fetched.
* max_fetch_size &lt;= 0 means no limit. default value is 1000000.
* @param values output values; if sortKey is not found, then it will not appear in values.
* the returned sortKey is just the same one in incoming sortKeys.
* @return true if all data is fetched; false if only partial data is fetched.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">multiGet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;</span> <span class="n">sortKeys</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxFetchCount</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxFetchSize</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">multiGet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;</span> <span class="n">sortKeys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定maxFetchCount和maxFetchSize。</li>
<li>参数:
<ul>
<li>传入参数:需传入TableName、HashKey、SortKeys;选择性传入maxFetchCount、maxFetchSize。</li>
<li>传出参数:数据通过values传出,values由用户在调用前new出来。</li>
<li>SortKeys如果非空,则只读取指定的数据;SortKeys如果为空,则表示读取该HashKey下的所有数据。</li>
<li>maxFetchCount和maxFetchSize用于限制读取的数据量,maxFetchCount表示最多读取的数据条数,maxFetchSize表示最多读取的数据字节数,两者任一达到限制就停止读取。</li>
</ul>
</li>
<li>返回值:如果用户指定了maxFetchCount或者maxFetchSize,单次查询可能只获取到部分结果。如果所有满足条件的数据都已经获取到,则返回true;否则返回false。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<p>multiGet还有另外一个版本的接口,可以支持SortKey的<strong>范围查询</strong><strong>条件过滤</strong>,只读取满足特定条件的数据。并且从1.8.0开始在MultiGetOptions中增加了reverse参数,支持<strong>逆向扫描</strong>数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">enum</span> <span class="nc">FilterType</span> <span class="o">{</span>
<span class="no">FT_NO_FILTER</span><span class="o">(</span><span class="mi">0</span><span class="o">),</span>
<span class="no">FT_MATCH_ANYWHERE</span><span class="o">(</span><span class="mi">1</span><span class="o">),</span> <span class="c1">// match filter string at any position</span>
<span class="no">FT_MATCH_PREFIX</span><span class="o">(</span><span class="mi">2</span><span class="o">),</span> <span class="c1">// match filter string at prefix</span>
<span class="no">FT_MATCH_POSTFIX</span><span class="o">(</span><span class="mi">3</span><span class="o">);</span> <span class="c1">// match filter string at postfix</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MultiGetOptions</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">startInclusive</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> <span class="c1">// if the startSortKey is included</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// if the stopSortKey is included</span>
<span class="kd">public</span> <span class="nc">FilterType</span> <span class="n">sortKeyFilterType</span> <span class="o">=</span> <span class="nc">FilterType</span><span class="o">.</span><span class="na">FT_NO_FILTER</span><span class="o">;</span> <span class="c1">// filter type for sort key</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKeyFilterPattern</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="c1">// filter pattern for sort key</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">noValue</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// only fetch hash_key and sort_key, but not fetch value</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">reverse</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// if search in reverse direction</span>
<span class="o">}</span>
<span class="cm">/**
* Get multiple key-values under the same hashKey with sortKey range limited.
* @param tableName table name
* @param hashKey used to decide which partition the key may exist
* should not be null or empty.
* @param startSortKey the start sort key.
* null means "".
* @param stopSortKey the stop sort key.
* null or "" means fetch to the last sort key.
* @param options multi-get options.
* @param maxFetchCount max count of kv pairs to be fetched
* maxFetchCount &lt;= 0 means no limit. default value is 100
* @param maxFetchSize max size of kv pairs to be fetched.
* maxFetchSize &lt;= 0 means no limit. default value is 1000000.
* @param values output values; if sortKey is not found, then it will not appear in values.
* the returned sortKey is just the same one in incoming sortKeys.
* @return true if all data is fetched; false if only partial data is fetched.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">multiGet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">stopSortKey</span><span class="o">,</span> <span class="nc">MultiGetOptions</span> <span class="n">options</span><span class="o">,</span>
<span class="kt">int</span> <span class="n">maxFetchCount</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxFetchSize</span><span class="o">,</span>
<span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">multiGet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">stopSortKey</span><span class="o">,</span> <span class="nc">MultiGetOptions</span> <span class="n">options</span><span class="o">,</span>
<span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定maxFetchCount和maxFetchSize。</li>
<li>参数:
<ul>
<li>传入参数:需传入TableName、HashKey、StartSortKey、StopSortKey、MultiGetOptions;选择性传入maxFetchCount、maxFetchSize。</li>
<li>传出参数:数据通过values传出,values由用户在调用前new出来。</li>
<li>StopSortKeys如果为空,不论stopInclusive为何值,都会读到该HashKey的SortKey结束。</li>
<li>maxFetchCount和maxFetchSize用于限制读取的数据量,maxFetchCount表示最多读取的数据条数,maxFetchSize表示最多读取的数据字节数,两者任一达到限制就停止读取。需要注意的是,PegasusServer从1.12.3开始限制一次性读取的数据(包括过期和条件过滤的数据)为3000条,该接口读取的有效数据可能会小于期望的数值</li>
<li>MultiGetOptions说明:
<ul>
<li>startInclusive:是否包含StartSortKey,默认为true。</li>
<li>stopInclusive:是否包含StopSortKey,默认为false。</li>
<li>sortKeyFilterType:SortKey的过滤类型,包括无过滤、任意位置匹配、前缀匹配和后缀匹配,默认无过滤。</li>
<li>sortKeyFilterPattern:SortKey的过滤模式串,空串相当于无过滤。</li>
<li>noValue:只返回HashKey和SortKey,不返回Value数据,默认为false。</li>
<li>reverse:是否逆向扫描数据库,从后往前查找数据。但是查找得到的结果在list中还是按照SortKey从小到大顺序存放。从Pegasus Server 1.8.0时开始支持。</li>
</ul>
</li>
<li>返回值:如果读取了所有满足条件的数据,返回true;如果只读取了部分满足条件的数据,返回false。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
<li>示例:获取某个HashKey下的所有数据(注意如果数据条数太多容易超时)
<ul>
<li>multiGet(hashKey, null, null, new MultiGetOptions(), -1, -1, values);</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="batchmultiget">batchMultiGet</h3>
<p>对multiGet函数的批量封装。该函数并发地向server发送异步请求,并等待结果。如果有任意一个请求失败,就提前终止并抛出异常。如果抛出了异常,则values中的结果是未定义的。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch get multiple values under the same hash key.
* Will terminate immediately if any error occurs.
* @param tableName table name
* @param keys List{hashKey,List{sortKey}}; if List{sortKey} is null or empty, means fetch all
* sortKeys under the hashKey.
* @param values output values; should be created by caller; if succeed, the size of values will
* be same with keys; the data for keys[i] is stored in values[i].
* @throws PException throws exception if any error occurs.
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchMultiGet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;&gt;&gt;</span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">HashKeyData</span><span class="o">&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Keys。Keys是一个Pair列表,Pair的左值是hashKey,右值是sortKey列表;如果Pair的右值为null或者空列表,则获取该hashKey下的所有数据。</li>
<li>传出参数:Values。该List需由调用者创建;如果读取成功,Values[i]中存放Keys[i]对应的结果。</li>
</ul>
</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,只要任意一个失败都会抛出异常。</li>
</ul>
<h3 id="batchmultiget2">batchMultiGet2</h3>
<p>对multiGet函数的批量封装。该函数并发地向server发送异步请求,并等待结果。但与上面batchMultiGet不同的是,无论请求成功还是失败,它都会等待所有请求结束。</p>
<p>用户可以根据results中的PException是否设置来判断请求成功还是失败,并可以选择只使用成功的结果。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch get multiple values under the same hash key.
* Will wait for all requests done even if some error occurs.
* @param tableName table name
* @param keys List{hashKey,List{sortKey}}; if List{sortKey} is null or empty, means fetch all
* sortKeys under the hashKey.
* @param results output results; should be created by caller; after call done, the size of results will
* be same with keys; the results[i] is a Pair:
* - if Pair.left != null : means query keys[i] failed, Pair.left is the exception.
* - if Pair.left == null : means query keys[i] succeed, Pair.right is the result value.
* @return succeed count.
* @throws PException
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchMultiGet2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;&gt;&gt;</span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">,</span> <span class="nc">HashKeyData</span><span class="o">&gt;&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Keys。Keys是一个Pair列表,Pair的左值是hashKey,右值是sortKey列表;如果Pair的右值为null或者空列表,则获取该hashKey下的所有数据。</li>
<li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Keys[i]对应的结果;如果Results[i].left不为null(PException已设置),表示对Keys[i]的请求失败。</li>
</ul>
</li>
<li>返回值:请求成功的个数。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,用户可以选择只使用成功的结果。</li>
</ul>
<h3 id="set">set</h3>
<p>写单行数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Set value.
* @param tableName TableHandler name
* @param hashKey used to decide which partition to put this k-v,
* if null or length == 0, means hash key is "".
* @param sortKey all the k-v under hashKey will be sorted by sortKey,
* if null or length == 0, means sort key is "".
* @param value should not be null
* @param ttl_seconds time to live in seconds,
* 0 means no ttl. default value is 0.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">set</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">value</span><span class="o">,</span> <span class="kt">int</span> <span class="n">ttl_seconds</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">set</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">value</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定TTL时间。</li>
<li>参数:需传入TableName、HashKey、SortKey、value;选择性传入TTL,TTL必须&gt;=0, 当&lt;0时会抛出PException异常。</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL&lt;0等,会抛出 PException。</li>
</ul>
<h3 id="batchset">batchSet</h3>
<p>写一批数据,对set函数的批量封装。该函数并发地向server发送异步请求,并等待结果。如果有任意一个请求失败,就提前终止并抛出异常。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch set lots of values.
* @param tableName TableHandler name
* @param items list of items.
* @throws PException throws exception if any error occurs.
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchSet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">SetItem</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、Items。</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,只要任意一个失败都会抛出异常。</li>
</ul>
<h3 id="batchset2">batchSet2</h3>
<p>对set函数的批量封装。该函数并发地向server发送异步请求,并等待结果。但与上面batchSet不同的是,无论请求成功还是失败,它都会等待所有请求结束。</p>
<p>用户可以根据results中的PException是否设置来判断请求成功还是失败,并可以选择只使用成功的结果。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch set lots of values.
* Will wait for all requests done even if some error occurs.
* @param tableName table name
* @param items list of items.
* @param results output results; should be created by caller; after call done, the size of results will
* be same with items; the results[i] is a PException:
* - if results[i] != null : means set items[i] failed, results[i] is the exception.
* - if results[i] == null : means set items[i] succeed.
* @return succeed count.
* @throws PException
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchSet2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">SetItem</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Items。</li>
<li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Items[i]对应的结果;如果Results[i]不为null(PException已设置),表示对Items[i]的请求失败。</li>
</ul>
</li>
<li>返回值:请求成功的个数。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,用户可以选择只使用成功的结果。</li>
</ul>
<h3 id="multiset">multiSet</h3>
<p>写同一HashKey下的多行数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Set multiple value under the same hash key.
* @param tableName table name
* @param hashKey used to decide which partition to put this k-v,
* should not be null or empty.
* @param values all &lt;sortkey,value&gt; pairs to be set,
* should not be null or empty.
* @param ttl_seconds time to live in seconds,
* 0 means no ttl. default value is 0.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">multiSet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">values</span><span class="o">,</span> <span class="kt">int</span> <span class="n">ttl_seconds</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">multiSet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">values</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定TTL时间。</li>
<li>参数:需传入TableName、HashKey、Values;选择性传入TTL,TTL必须&gt;=0, 当&lt;0时会抛出PException异常。
<ul>
<li>Values是Pair列表,Pair的第一个元素是SortKey,第二个元素为value。</li>
</ul>
</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL&lt;0等,会抛出 PException。</li>
</ul>
<h3 id="batchmultiset">batchMultiSet</h3>
<p>对multiSet函数的批量封装。该函数并发地向server发送异步请求,并等待结果。如果有任意一个请求失败,就提前终止并抛出异常。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch set multiple value under the same hash key.
* Will terminate immediately if any error occurs.
* @param tableName TableHandler name
* @param items list of items.
* @param ttl_seconds time to live in seconds,
* 0 means no ttl. default value is 0.
* @throws PException throws exception if any error occurs.
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchMultiSet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">HashKeyData</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">,</span> <span class="kt">int</span> <span class="n">ttl_seconds</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchMultiSet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">HashKeyData</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定TTL时间。</li>
<li>参数:需传入TableName、Items;选择性传入TTL,TTL必须&gt;=0, 当&lt;0时会抛出PException异常。</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL&lt;0等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,只要任意一个失败都会抛出异常。</li>
</ul>
<h3 id="batchmultiset2">batchMultiSet2</h3>
<p>对multiSet函数的批量封装。该函数并发地向server发送异步请求,并等待结果。但与上面batchMultiSet不同的是,无论请求成功还是失败,它都会等待所有请求结束。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch set multiple value under the same hash key.
* Will wait for all requests done even if some error occurs.
* @param tableName table name
* @param items list of items.
* @param ttl_seconds time to live in seconds,
* 0 means no ttl. default value is 0.
* @param results output results; should be created by caller; after call done, the size of results will
* be same with items; the results[i] is a PException:
* - if results[i] != null : means set items[i] failed, results[i] is the exception.
* - if results[i] == null : means set items[i] succeed.
* @return succeed count.
* @throws PException
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchMultiSet2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">HashKeyData</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">,</span> <span class="kt">int</span> <span class="n">ttl_seconds</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchMultiSet2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">HashKeyData</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定TTL时间。</li>
<li>参数:
<ul>
<li>传入参数:TableName、Items;选择性传入TTL,TTL必须&gt;=0, 当&lt;0时会抛出PException异常。</li>
<li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Items[i]对应的结果;如果Results[i]不为null(PException已设置),表示对Items[i]的请求失败。</li>
</ul>
</li>
<li>返回值:请求成功的个数。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在、TTL&lt;0等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,用户可以选择只使用成功的结果。</li>
</ul>
<h3 id="del">del</h3>
<p>删单行数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Delete value.
* @param tableName TableHandler name
* @param hashKey used to decide which partition to put this k-v,
* if null or length == 0, means hash key is "".
* @param sortKey all the k-v under hashKey will be sorted by sortKey,
* if null or length == 0, means sort key is "".
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">del</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKey。</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="batchdel">batchDel</h3>
<p>删除一批数据,对del函数的批量封装。该函数并发地向server发送异步请求,并等待结果。如果有任意一个请求失败,就提前终止并抛出异常。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch delete values of different keys.
* Will terminate immediately if any error occurs.
* @param tableName table name
* @param keys hashKey and sortKey pair list.
* @throws PException throws exception if any error occurs.
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchDel</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">keys</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、Keys。</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,只要任意一个失败都会抛出异常。</li>
</ul>
<h3 id="batchdel2">batchDel2</h3>
<p>对del函数的批量封装。该函数并发地向server发送异步请求,并等待结果。但与上面batchDel不同的是,无论请求成功还是失败,它都会等待所有请求结束。</p>
<p>用户可以根据results中的PException是否设置来判断请求成功还是失败,并可以选择只使用成功的结果。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch delete values of different keys.
* Will wait for all requests done even if some error occurs.
* @param tableName table name
* @param keys hashKey and sortKey pair list.
* @param results output results; should be created by caller; after call done, the size of results will
* be same with keys; the results[i] is a PException:
* - if results[i] != null : means del keys[i] failed, results[i] is the exception.
* - if results[i] == null : means del keys[i] succeed.
* @return succeed count.
* @throws PException
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchDel2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]&gt;&gt;</span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Keys。</li>
<li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Keys[i]对应的结果;如果Results[i]不为null(PException已设置),表示对Keys[i]的请求失败。</li>
</ul>
</li>
<li>返回值:请求成功的个数。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,用户可以选择只使用成功的结果。</li>
</ul>
<h3 id="multidel">multiDel</h3>
<p>删同一HashKey下的多行数据。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Delete specified sort keys under the same hash key.
* @param tableName table name
* @param hashKey used to decide which partition to put this k-v,
* should not be null or empty.
* @param sortKeys specify sort keys to be deleted.
* should not be empty.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">multiDel</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;</span> <span class="n">sortKeys</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKeys。
<ul>
<li>SortKeys不允许为空,如果不知道该HashKey下面有哪些SortKey,可以通过下面的multiGetSortKeys方法获取。</li>
</ul>
</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="batchmultidel">batchMultiDel</h3>
<p>对multiDel函数的批量封装。该函数并发地向server发送异步请求,并等待结果。如果有任意一个请求失败,就提前终止并抛出异常。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch delete specified sort keys under the same hash key.
* Will terminate immediately if any error occurs.
* @param tableName table name
* @param keys List{hashKey,List{sortKey}}
* @throws PException throws exception if any error occurs.
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">batchMultiDel</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;&gt;&gt;</span> <span class="n">keys</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、Keys。Keys是一个Pair列表,Pair的左值是hashKey,右值是非空的sortKey列表。</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,只要任意一个失败都会抛出异常。</li>
</ul>
<h3 id="batchmultidel2">batchMultiDel2</h3>
<p>对del函数的批量封装。该函数并发地向server发送异步请求,并等待结果。但与上面batchMultiDel不同的是,无论请求成功还是失败,它都会等待所有请求结束。</p>
<p>用户可以根据results中的PException是否设置来判断请求成功还是失败,并可以选择只使用成功的结果。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Batch delete specified sort keys under the same hash key.
* Will wait for all requests done even if some error occurs.
* @param tableName table name
* @param keys List{hashKey,List{sortKey}}
* @param results output results; should be created by caller; after call done, the size of results will
* be same with keys; the results[i] is a PException:
* - if results[i] != null : means del keys[i] failed, results[i] is the exception.
* - if results[i] == null : means del keys[i] succeed.
* @return succeed count.
* @throws PException
*
* Notice: the method is not atomic, that means, maybe some keys succeed but some keys failed.
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">batchMultiDel2</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Pair</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;&gt;&gt;</span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">PException</span><span class="o">&gt;</span> <span class="n">results</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:TableName、Keys。Keys是一个Pair列表,Pair的左值是hashKey,右值是非空的sortKey列表。</li>
<li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Keys[i]对应的结果;如果Results[i]不为null(PException已设置),表示对Keys[i]的请求失败。</li>
</ul>
</li>
<li>返回值:请求成功的个数。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况,用户可以选择只使用成功的结果。</li>
</ul>
<h3 id="delrange">delRange</h3>
<p>删除同一HashKey下,SortKey值在startSortKey和stopSortKey范围内的数据。删除过程中若发生错误,不影响已经删除的数据,同时会标记该范围内未删除的第一个SortKey。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Delete key-values within range of startSortKey and stopSortKey under hashKey. Will terminate
* immediately if any error occurs.
*
* @param tableName table name
* @param hashKey used to decide which partition the key may exist, should not be null or empty.
* @param startSortKey the start sort key. null or "" means fetch to the first sort key.
* @param stopSortKey the stop sort key. null or "" means fetch to the last sort key.
* @param options del range options.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">delRange</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">stopSortKey</span><span class="o">,</span><span class="nc">DelRangeOptions</span> <span class="n">options</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DelRangeOptions</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">nextSortKey</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">startInclusive</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> <span class="c1">// whether the startSortKey is included</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// whether the stopSortKey is included</span>
<span class="kd">public</span> <span class="nc">FilterType</span> <span class="n">sortKeyFilterType</span> <span class="o">=</span> <span class="nc">FilterType</span><span class="o">.</span><span class="na">FT_NO_FILTER</span><span class="o">;</span> <span class="c1">// filter type for sort key</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKeyFilterPattern</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="c1">// filter pattern for sort key</span>
<span class="o">}</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:
<ul>
<li>传入参数:
<ul>
<li>startSortKey和stopSortKey是sortkey的起止key值。</li>
<li>DelRangeOptions:
<ul>
<li>nextSortKey:将要删除的第一个sortKey值,默认为null, 在删除开始后会动态记录下一个要删除的值。特别的,当删除过程中出现错误时,该参数可以记录接下来需要继续删除的sortKey</li>
<li>startInclusive:是否包含StartSortKey,默认为true</li>
<li>stopInclusive:是否包含StopSortKey,默认为false</li>
<li>sortKeyFilterType:SortKey的过滤类型,包括无过滤、任意位置匹配、前缀匹配和后缀匹配,默认无过滤。</li>
<li>sortKeyFilterPattern:SortKey的过滤模式串,空串相当于无过滤。</li>
</ul>
</li>
</ul>
</li>
<li>传出参数:无。</li>
</ul>
</li>
<li>返回值:无。</li>
<li>异常:如果出现异常,譬如参数错误、表名不存在、超时等,会抛出 PException。</li>
<li>注意:该方法不是原子的,有可能出现部分成功部分失败的情况。</li>
</ul>
<h3 id="incr">incr</h3>
<p>单行原子增(减)操作。详细说明参见<a href="/zh/api/single-atomic#原子增减">单行原子操作</a></p>
<p>该操作先将key所指向的value的字节串转换为int64类型(实现上类似于Java的<a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#parseLong(java.lang.String)">Long.parseLong()</a>函数),然后加上increment,将结果转换为字节串设置为新值。</p>
<p>当参数increment为正数时,即原子加;当参数increment为负数时,即原子减。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Atomically increment value.
*
* @param tableName the table name.
* @param hashKey the hash key to increment.
* @param sortKey the sort key to increment.
* @param increment the increment to be added to the old value.
* @return the new value.
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="kt">long</span> <span class="nf">incr</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">,</span> <span class="kt">long</span> <span class="n">increment</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKey、Increment。</li>
<li>返回值:操作成功后的新值。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。另外以下情况也会抛出异常:
<ul>
<li>旧值转换为int64时出错,譬如不是合法的数字或者超出int64范围。</li>
<li>旧值加上increment后的结果超出int64范围。</li>
</ul>
</li>
<li>其他说明:
<ul>
<li>如果旧值不存在,则把旧值当做0处理,即新值等于increment。</li>
<li>TTL语义:如果旧值存在,新值的TTL和旧值保持一致;如果旧值不存在,新值将不设TTL。</li>
</ul>
</li>
</ul>
<p>从Pegasus Server v1.11.1版本开始支持在incr操作时修改TTL,需使用<a href="https://github.com/XiaoMi/pegasus-java-client/releases/tag/1.11.2-thrift-0.11.0-inlined-release">Pegasus Java Client 1.11.2-thrift-0.11.0-inlined-release</a>及以上版本来使用这个功能。</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/**
* Atomically increment value.
*
* @param tableName the table name.
* @param hashKey the hash key to increment.
* @param sortKey the sort key to increment.
* @param increment the increment to be added to the old value.
* @param ttlSeconds time to live in seconds for the new value.
* should be no less than -1. for the second method, the ttlSeconds is 0.
* - if ttlSeconds == 0, the semantic is the same as redis:
* - normally, increment will preserve the original ttl.
* - if old data is expired by ttl, then set initial value to 0 and set no ttl.
* - if ttlSeconds &gt; 0, then update with the new ttl if increment succeed.
* - if ttlSeconds == -1, then update to no ttl if increment succeed.
* @return the new value.
* @throws PException throws exception if any error occurs.
*/
public long incr(String tableName, byte[] hashKey, byte[] sortKey, long increment, int ttlSeconds) throws PException;
public long incr(String tableName, byte[] hashKey, byte[] sortKey, long increment) throws PException;
</code></pre></div></div>
<p>注:</p>
<ul>
<li>除了TTL之外,其他语义都与前面相同。</li>
<li>TTL操作说明:
<ul>
<li>如果参数ttlSeconds == 0,则和redis语义保持一致:如果旧值存在,新值的TTL和旧值保持一致;如果旧值不存在,新值将不设TTL。</li>
<li>如果参数ttlSeconds &gt; 0,则将TTL设置为新值。</li>
<li>如果参数ttlSeconds == -1,则清理掉TTL,即新值不再设置TTL。</li>
<li>如果参数ttlSeconds &lt; -1,则抛出异常。</li>
</ul>
</li>
</ul>
<h3 id="checkandset">checkAndSet</h3>
<p>单HashKey数据的原子CAS操作(可以理解为<strong>单行原子操作</strong>)。详细说明参见<a href="/zh/api/single-atomic#cas操作">单行原子操作</a></p>
<p>该操作先对某个SortKey(称之为CheckSortKey)的value做条件检查:</p>
<ul>
<li>如果检查的条件满足,则将另一个SortKey(称之为SetSortKey)的value设置为新值。</li>
<li>如果检查的条件不满足,则不执行set操作。</li>
</ul>
<p>CheckSortKey和SetSortKey可以相同也可以不同。</p>
<p>用户还可以设置<code class="language-plaintext highlighter-rouge">CheckAndSetOptions.returnCheckValue</code>来获取CheckSortKey对应的value。如果CheckSortKey和SetSortKey相同并且set成功,则获取set之前的旧值。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">enum</span> <span class="nc">CheckType</span> <span class="o">{</span>
<span class="no">CT_NO_CHECK</span><span class="o">(</span><span class="mi">0</span><span class="o">),</span>
<span class="c1">// appearance</span>
<span class="no">CT_VALUE_NOT_EXIST</span><span class="o">(</span><span class="mi">1</span><span class="o">),</span> <span class="c1">// value is not exist</span>
<span class="no">CT_VALUE_NOT_EXIST_OR_EMPTY</span><span class="o">(</span><span class="mi">2</span><span class="o">),</span> <span class="c1">// value is not exist or value is empty</span>
<span class="no">CT_VALUE_EXIST</span><span class="o">(</span><span class="mi">3</span><span class="o">),</span> <span class="c1">// value is exist</span>
<span class="no">CT_VALUE_NOT_EMPTY</span><span class="o">(</span><span class="mi">4</span><span class="o">),</span> <span class="c1">// value is exist and not empty</span>
<span class="c1">// match</span>
<span class="no">CT_VALUE_MATCH_ANYWHERE</span><span class="o">(</span><span class="mi">5</span><span class="o">),</span> <span class="c1">// operand matches anywhere in value</span>
<span class="no">CT_VALUE_MATCH_PREFIX</span><span class="o">(</span><span class="mi">6</span><span class="o">),</span> <span class="c1">// operand matches prefix in value</span>
<span class="no">CT_VALUE_MATCH_POSTFIX</span><span class="o">(</span><span class="mi">7</span><span class="o">),</span> <span class="c1">// operand matches postfix in value</span>
<span class="c1">// bytes compare</span>
<span class="no">CT_VALUE_BYTES_LESS</span><span class="o">(</span><span class="mi">8</span><span class="o">),</span> <span class="c1">// bytes compare: value &lt; operand</span>
<span class="no">CT_VALUE_BYTES_LESS_OR_EQUAL</span><span class="o">(</span><span class="mi">9</span><span class="o">),</span> <span class="c1">// bytes compare: value &lt;= operand</span>
<span class="no">CT_VALUE_BYTES_EQUAL</span><span class="o">(</span><span class="mi">10</span><span class="o">),</span> <span class="c1">// bytes compare: value == operand</span>
<span class="no">CT_VALUE_BYTES_GREATER_OR_EQUAL</span><span class="o">(</span><span class="mi">11</span><span class="o">),</span> <span class="c1">// bytes compare: value &gt;= operand</span>
<span class="no">CT_VALUE_BYTES_GREATER</span><span class="o">(</span><span class="mi">12</span><span class="o">),</span> <span class="c1">// bytes compare: value &gt; operand</span>
<span class="c1">// int compare: first transfer bytes to int64; then compare by int value</span>
<span class="no">CT_VALUE_INT_LESS</span><span class="o">(</span><span class="mi">13</span><span class="o">),</span> <span class="c1">// int compare: value &lt; operand</span>
<span class="no">CT_VALUE_INT_LESS_OR_EQUAL</span><span class="o">(</span><span class="mi">14</span><span class="o">),</span> <span class="c1">// int compare: value &lt;= operand</span>
<span class="no">CT_VALUE_INT_EQUAL</span><span class="o">(</span><span class="mi">15</span><span class="o">),</span> <span class="c1">// int compare: value == operand</span>
<span class="no">CT_VALUE_INT_GREATER_OR_EQUAL</span><span class="o">(</span><span class="mi">16</span><span class="o">),</span> <span class="c1">// int compare: value &gt;= operand</span>
<span class="no">CT_VALUE_INT_GREATER</span><span class="o">(</span><span class="mi">17</span><span class="o">);</span> <span class="c1">// int compare: value &gt; operand</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">CheckAndSetOptions</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="n">setValueTTLSeconds</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="c1">// time to live in seconds of the set value, 0 means no ttl.</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">returnCheckValue</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// if return the check value in results.</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">CheckAndSetResult</span> <span class="o">{</span>
<span class="cm">/**
* return value for checkAndSet
*
* @param setSucceed true if set value succeed.
* @param checkValueReturned true if the check value is returned.
* @param checkValueExist true if the check value is exist; can be used only when checkValueReturned is true.
* @param checkValue return the check value if exist; can be used only when checkValueExist is true.
*/</span>
<span class="kt">boolean</span> <span class="n">setSucceed</span><span class="o">;</span>
<span class="kt">boolean</span> <span class="n">checkValueReturned</span><span class="o">;</span>
<span class="kt">boolean</span> <span class="n">checkValueExist</span><span class="o">;</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">checkValue</span><span class="o">;</span>
<span class="o">}</span>
<span class="cm">/**
* Atomically check and set value by key.
* If the check condition is satisfied, then apply to set value.
*
* @param tableName the table name.
* @param hashKey the hash key to check and set.
* @param checkSortKey the sort key to check.
* @param checkType the check type.
* @param checkOperand the check operand.
* @param setSortKey the sort key to set value if check condition is satisfied.
* @param setValue the value to set if check condition is satisfied.
* @param options the check-and-set options.
* @return CheckAndSetResult
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="nc">PegasusTableInterface</span><span class="o">.</span><span class="na">CheckAndSetResult</span> <span class="nf">checkAndSet</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">checkSortKey</span><span class="o">,</span>
<span class="nc">CheckType</span> <span class="n">checkType</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">checkOperand</span><span class="o">,</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">setSortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">setValue</span><span class="o">,</span>
<span class="nc">CheckAndSetOptions</span> <span class="n">options</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、CheckSortKey、CheckType、CheckOperand、SetSortKey、SetValue、Options。
<ul>
<li>checkSortKey、checkType、checkOperand:用于指定检查的条件。</li>
<li>setSortKey、setValue:用于指定条件检查成功后要set的新值。</li>
<li>options:其他选项,包括:
<ul>
<li>setValueTTLSeconds:新值的TTL时间;TTL必须&gt;=0,0表示不设置TTL限制,当&lt;0时将抛出PException异常。</li>
<li>returnCheckValue:是否需要返回CheckSortKey对应的value。</li>
</ul>
</li>
</ul>
</li>
<li>返回值:CheckAndSetResult,包括:
<ul>
<li>setSucceed:是否set成功。</li>
<li>checkValueReturned:是否返回了CheckSortKey对应的value。</li>
<li>checkValueExist:CheckSortKey对应的value是否存在;该域只有在<code class="language-plaintext highlighter-rouge">checkValueReturned=true</code>时有意义。</li>
<li>checkValue:CheckSortKey对应的value值;该域只有在<code class="language-plaintext highlighter-rouge">checkValueExist=true</code>时有意义。</li>
</ul>
</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL&lt;0等,会抛出 PException。另外以下情况也会抛出异常:
<ul>
<li>如果CheckType为<code class="language-plaintext highlighter-rouge">int compare</code>类型的操作,且CheckOperand或者CheckValue转换为int64时出错,譬如不是合法的数字或者超出int64范围。</li>
</ul>
</li>
</ul>
<h3 id="checkandmutate">checkAndMutate</h3>
<p>checkAndMutate是<a href="#checkandset">checkAndSet</a>的扩展版本:checkAndSet只允许set一个值,而checkAndMutate允许在单个原子操作中set或者del多个值。该接口从<a href="https://github.com/XiaoMi/pegasus-java-client/releases/tag/1.11.0-thrift-0.11.0-inlined-release">Pegasus Java Client 1.11.0-thrift-0.11.0-inlined-release</a>版本开始提供。</p>
<p>为此,我们提供了一个包装类<a href="https://github.com/XiaoMi/pegasus-java-client/blob/thrift-0.11.0-inlined/src/main/java/com/xiaomi/infra/pegasus/client/Mutations.java">Mutations</a>,用户可以预先设置需要实施的set或者del操作。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">CheckAndMutateResult</span> <span class="o">{</span>
<span class="cm">/**
* return value for checkAndMutate
*
* @param mutateSucceed true if mutate succeed.
* @param checkValueReturned true if the check value is returned.
* @param checkValueExist true if the check value is exist; can be used only when
* checkValueReturned is true.
* @param checkValue return the check value if exist; can be used only when checkValueExist is
* true.
*/</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">mutateSucceed</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">checkValueReturned</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">checkValueExist</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">checkValue</span><span class="o">;</span>
<span class="o">}</span>
<span class="cm">/**
* atomically check and mutate by key, async version. if the check condition is satisfied, then
* apply to mutate.
*
* @param hashKey the hash key to check and mutate.
* @param checkSortKey the sort key to check.
* @param checkType the check type.
* @param checkOperand the check operand.
* @param mutations the list of mutations to perform if check condition is satisfied.
* @param options the check-and-mutate options.
* @param timeout how long will the operation timeout in milliseconds. if timeout &gt; 0, it is a
* timeout value for current op, else the timeout value in the configuration file will be
* used.
* @return the future for current op
* &lt;p&gt;Future return: On success: return CheckAndMutateResult. On failure: a throwable, which
* is an instance of PException
* &lt;p&gt;Thread safety: All the listeners for the same table are guaranteed to be dispatched in
* the same thread, so all the listeners for the same future are guaranteed to be executed as
* the same order as the listeners added. But listeners for different tables are not
* guaranteed to be dispatched in the same thread.
*/</span>
<span class="nc">Future</span><span class="o">&lt;</span><span class="nc">CheckAndMutateResult</span><span class="o">&gt;</span> <span class="nf">asyncCheckAndMutate</span><span class="o">(</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">checkSortKey</span><span class="o">,</span>
<span class="nc">CheckType</span> <span class="n">checkType</span><span class="o">,</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">checkOperand</span><span class="o">,</span>
<span class="nc">Mutations</span> <span class="n">mutations</span><span class="o">,</span>
<span class="nc">CheckAndMutateOptions</span> <span class="n">options</span><span class="o">,</span>
<span class="kt">int</span> <span class="n">timeout</span> <span class="cm">/*ms*/</span><span class="o">);</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、CheckSortKey、CheckType、CheckOperand、Mutations、Options。
<ul>
<li>checkSortKey、checkType、checkOperand:用于指定检查的条件。</li>
<li>mutations:用于指定条件检查成功后要实施的set或者del操作。</li>
<li>options:其他选项,包括:
<ul>
<li>returnCheckValue:是否需要返回CheckSortKey对应的value。</li>
</ul>
</li>
</ul>
</li>
<li>返回值:CheckAndMutateResult,包括:
<ul>
<li>mutateSucceed:是否实施成功。</li>
<li>checkValueReturned:是否返回了CheckSortKey对应的value。</li>
<li>checkValueExist:CheckSortKey对应的value是否存在;该域只有在<code class="language-plaintext highlighter-rouge">checkValueReturned=true</code>时有意义。</li>
<li>checkValue:CheckSortKey对应的value值;该域只有在<code class="language-plaintext highlighter-rouge">checkValueExist=true</code>时有意义。</li>
</ul>
</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。另外以下情况也会抛出异常:
<ul>
<li>如果CheckType为<code class="language-plaintext highlighter-rouge">int compare</code>类型的操作,且CheckOperand或者CheckValue转换为int64时出错,譬如不是合法的数字或者超出int64范围。</li>
</ul>
</li>
</ul>
<h3 id="compareexchange">compareExchange</h3>
<p>compareExchange是<a href="#checkandset">checkAndSet</a>的特化版本:</p>
<ul>
<li>CheckSortKey和SetSortKey相同。</li>
<li>CheckType为CT_VALUE_BYTES_EQUAL。</li>
</ul>
<p>该方法语义就是:如果SortKey对应的value存在且等于期望的值,则将其设置为新值。详细说明参见<a href="/zh/api/single-atomic#cas操作">单行原子操作</a></p>
<p>该方法与C++库中常见的<a href="https://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange">atomic_compare_exchange</a>语义基本保持一致。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">CompareExchangeResult</span> <span class="o">{</span>
<span class="cm">/**
* return value for CompareExchange
*
* @param setSucceed true if set value succeed.
* @param actualValue return the actual value if set value failed; null means the actual value is not exist.
*/</span>
<span class="kt">boolean</span> <span class="n">setSucceed</span><span class="o">;</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">actualValue</span><span class="o">;</span>
<span class="o">}</span>
<span class="cm">/**
* Atomically compare and exchange value by key.
* &lt;p&gt;
* - if the original value for the key is equal to the expected value, then update it with the desired value,
* set CompareExchangeResult.setSucceed to true, and set CompareExchangeResult.actualValue to null because
* the actual value must be equal to the desired value.
* - if the original value for the key is not exist or not equal to the expected value, then set
* CompareExchangeResult.setSucceed to false, and set the actual value in CompareExchangeResult.actualValue.
* &lt;p&gt;
* This method is very like the C++ function in {https://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange}.
*
* @param tableName the table name.
* @param hashKey the hash key to compare and exchange.
* @param sortKey the sort key to compare and exchange.
* @param expectedValue the value expected to be found for the key.
* @param desiredValue the desired value to set if the original value for the key is equal to the expected value.
* @param ttlSeconds time to live in seconds of the desired value, 0 means no ttl.
* @return CompareExchangeResult
* @throws PException throws exception if any error occurs.
*/</span>
<span class="kd">public</span> <span class="nc">PegasusTableInterface</span><span class="o">.</span><span class="na">CompareExchangeResult</span> <span class="nf">compareExchange</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">,</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">expectedValue</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">desiredValue</span><span class="o">,</span>
<span class="kt">int</span> <span class="n">ttlSeconds</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKey、ExpectedValue、DesiredValue、ttlSeconds。
<ul>
<li>hashKey、sortKey:用于指定数据的key。</li>
<li>expectedValue:期望的旧值。</li>
<li>desiredValue:如果旧值等于expectedValue,需要设置的新值。</li>
<li>ttlSeconds:新值的TTL时间;TTL必须&gt;=0,0表示不设置TTL限制,当TTL&lt;0时将抛出PException异常。</li>
</ul>
</li>
<li>返回值:CompareExchangeResult,包括:
<ul>
<li>setSucceed:是否set成功,如果旧数据不存在,则set失败。</li>
<li>actualValue:如果set失败,返回该value的实际值;null表示不存在。</li>
</ul>
</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL&lt;0等,会抛出 PException。</li>
</ul>
<h3 id="ttl">ttl</h3>
<p>获取单行数据的TTL时间。TTL表示Time To Live,表示该数据还能存活多久。如果超过存活时间,数据就读不到了。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Get ttl time.
* @param tableName TableHandler name
* @param hashKey used to decide which partition to put this k-v,
* if null or length == 0, means hash key is "".
* @param sortKey all the k-v under hashKey will be sorted by sortKey,
* if null or length == 0, means sort key is "".
* @return ttl time in seconds; -1 if no ttl set; -2 if not exist.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">ttl</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKey。</li>
<li>返回值:TTL时间,单位为秒。如果该数据没有设置TTL,返回-1;如果该数据不存在,返回-2。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="exist">exist</h3>
<p>检查数据是否存在。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Check value exist by key from the cluster
* @param tableName TableHandler name
* @param hashKey used to decide which partition the key may exist.
* @param sortKey all keys under the same hashKey will be sorted by sortKey
*
* @return true if exist, false if not exist
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">exist</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKey</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、SortKey。</li>
<li>返回值:如果存在返回true,否则返回false。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="sortkeycount">sortKeyCount</h3>
<p>获取某个HashKey下所有SortKey的个数。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* @param tableName TableHandler name
* @param hashKey used to decide which partition the key may exist.
* @return the count result for the hashKey
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">long</span> <span class="nf">sortKeyCount</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey。</li>
<li>返回值:返回HashKey下所有SortKey的个数。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="multigetsortkeys">multiGetSortKeys</h3>
<p>获取某个HashKey下SortKey列表。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Get multiple sort keys under the same hash key.
* @param tableName table name
* @param hashKey used to decide which partition to put this k-v,
* should not be null or empty.
* @param maxFetchCount max count of k-v pairs to be fetched.
* max_fetch_count &lt;= 0 means no limit. default value is 100.
* @param maxFetchSize max size of k-v pairs to be fetched.
* max_fetch_size &lt;= 0 means no limit. default value is 1000000.
* @param sortKeys output sort keys.
* @return true if all data is fetched; false if only partial data is fetched.
* @throws PException
*/</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">multiGetSortKeys</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxFetchCount</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxFetchSize</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;</span> <span class="n">sortKeys</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">multiGetSortKeys</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="nc">List</span><span class="o">&lt;</span><span class="kt">byte</span><span class="o">[]&gt;</span> <span class="n">sortKeys</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>提供了两个版本的接口,其中第一个接口可以指定maxFetchCount和maxFetchSize。</li>
<li>参数:
<ul>
<li>传入参数:需传入TableName、HashKey;选择性传入maxFetchCount、maxFetchSize。</li>
<li>传出参数:数据通过sortKeys传出,sortKeys由用户在调用前new出来。</li>
<li>maxFetchCount和maxFetchSize用于限制读取的数据量,maxFetchCount表示最多读取的数据条数,maxFetchSize表示最多读取的数据字节数,两者任一达到限制就停止读取。</li>
</ul>
</li>
<li>返回值:如果用户指定了maxFetchCount或者maxFetchSize,单次查询可能只获取到部分结果。如果所有满足条件的数据都已经获取到,则返回true;否则返回false。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="getscanner">getScanner</h3>
<p>获取遍历某个HashKey下所有数据的迭代器,用于局部扫描。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">enum</span> <span class="nc">FilterType</span> <span class="o">{</span>
<span class="no">FT_NO_FILTER</span><span class="o">(</span><span class="mi">0</span><span class="o">),</span>
<span class="no">FT_MATCH_ANYWHERE</span><span class="o">(</span><span class="mi">1</span><span class="o">),</span> <span class="c1">// match filter string at any position</span>
<span class="no">FT_MATCH_PREFIX</span><span class="o">(</span><span class="mi">2</span><span class="o">),</span> <span class="c1">// match filter string at prefix</span>
<span class="no">FT_MATCH_POSTFIX</span><span class="o">(</span><span class="mi">3</span><span class="o">);</span> <span class="c1">// match filter string at postfix</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ScanOptions</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="n">timeoutMillis</span> <span class="o">=</span> <span class="mi">5000</span><span class="o">;</span> <span class="c1">// operation timeout in milli-seconds.</span>
<span class="c1">// if timeoutMillis &gt; 0, it is a timeout value for current op,</span>
<span class="c1">// else the timeout value in the configuration file will be used.</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="n">batchSize</span> <span class="o">=</span> <span class="mi">1000</span><span class="o">;</span> <span class="c1">// internal buffer batch size</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">startInclusive</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> <span class="c1">// if the startSortKey is included</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// if the stopSortKey is included</span>
<span class="kd">public</span> <span class="nc">FilterType</span> <span class="n">hashKeyFilterType</span> <span class="o">=</span> <span class="nc">FilterType</span><span class="o">.</span><span class="na">FT_NO_FILTER</span><span class="o">;</span> <span class="c1">// filter type for hash key</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKeyFilterPattern</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="c1">// filter pattern for hash key</span>
<span class="kd">public</span> <span class="nc">FilterType</span> <span class="n">sortKeyFilterType</span> <span class="o">=</span> <span class="nc">FilterType</span><span class="o">.</span><span class="na">FT_NO_FILTER</span><span class="o">;</span> <span class="c1">// filter type for sort key</span>
<span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">sortKeyFilterPattern</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="c1">// filter pattern for sort key</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="n">noValue</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> <span class="c1">// only fetch hash_key and sort_key, but not fetch value</span>
<span class="o">}</span>
<span class="cm">/**
* Get Scanner for {startSortKey, stopSortKey} within hashKey
* @param tableName TableHandler name
* @param hashKey used to decide which partition to put this k-v,
* @param startSortKey start sort key scan from
* if null or length == 0, means start from begin
* @param stopSortKey stop sort key scan to
* if null or length == 0, means stop to end
* @param options scan options like endpoint inclusive/exclusive
* @return scanner
* @throws PException
*/</span>
<span class="kd">public</span> <span class="nc">PegasusScannerInterface</span> <span class="nf">getScanner</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">hashKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">stopSortKey</span><span class="o">,</span> <span class="nc">ScanOptions</span> <span class="n">options</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、HashKey、StartSortKey、StopSortKey、ScanOptions。
<ul>
<li>StartSortKey和StopSortKey用于指定scan的返回,并通过ScanOptions指定区间的开闭。</li>
<li>如果StartSortKey为null,表示从头开始;如果StopSortKey为null,表示一直读到尾。</li>
<li>ScanOptions说明:
<ul>
<li>timeoutMillis:从server端读取数据的超时时间,单位毫秒,默认值为5000。</li>
<li>batchSize:从server端读取数据时每批数据的个数,默认值为1000。</li>
<li>startInclusive:是否包含StartSortKey,默认为true。</li>
<li>stopInclusive:是否包含StopSortKey,默认为false。</li>
<li>hashKeyFilterType:HashKey的过滤类型,包括无过滤、任意位置匹配、前缀匹配和后缀匹配,默认无过滤。</li>
<li>hashKeyFilterPattern:HashKey的过滤模式串,空串相当于无过滤。</li>
<li>sortKeyFilterType:SortKey的过滤类型,包括无过滤、任意位置匹配、前缀匹配和后缀匹配,默认无过滤。</li>
<li>sortKeyFilterPattern:SortKey的过滤模式串,空串相当于无过滤。</li>
<li>noValue:只返回HashKey和SortKey,不返回Value数据,默认为false。</li>
</ul>
</li>
</ul>
</li>
<li>返回值:返回迭代器PegasusScannerInterface。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h3 id="getunorderedscanner">getUnorderedScanner</h3>
<p>获取遍历整个表的所有数据的迭代器,用于全局扫描。</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/**
* Get Scanners for all data in database
* @param tableName TableHandler name
* @param maxSplitCount how many scanner expected
* @param options scan options like batchSize
* @return scanners, count of which would be no more than maxSplitCount
* @throws PException
*/
public List&lt;PegasusScannerInterface&gt; getUnorderedScanners(String tableName, int maxSplitCount, ScanOptions options) throws PException;
</code></pre></div></div>
<p>注:</p>
<ul>
<li>参数:需传入TableName、maxSplitCount、ScanOptions。
<ul>
<li>maxSplitCount:用于决定返回的迭代器的个数。当返回多个迭代器时,每个迭代器可以访问表中的部分数据。通过返回迭代器列表,用户可以进行并发scan或者在MapReduce中使用。如果不需要多个迭代器,可以将其设置为1。</li>
<li>ScanOptions同上。</li>
</ul>
</li>
<li>返回值:返回迭代器PegasusScannerInterface列表。</li>
<li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误等,会抛出 PException。</li>
</ul>
<h2 id="创建table实例">创建Table实例</h2>
<p>通过<code class="language-plaintext highlighter-rouge">PegasusClientInterface::openTable()</code>方法获取PegasusTableInterface的对象实例:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* Open a table. Please notice that pegasus support two kinds of API:
* 1. the client-interface way, which is provided in this class.
* 2. the table-interface way, which is provided by {@link PegasusTableInterface}.
* With the client-interface, you don't need to create PegasusTableInterface by openTable, so
* you can access the pegasus cluster conveniently. However, the client-interface's api also has
* some restrictions:
* 1. we don't provide async methods in client-interface.
* 2. the timeout in client-interface isn't as accurate as the table-interface.
* 3. the client-interface may throw an exception when open table fails. It means that
* you may need to handle this exception in every data access operation, which is annoying.
* 4. You can't specify a per-operation timeout.
* So we recommend you to use the table-interface.
*
* @param tableName the table should be exist on the server, which is created before by
* the system administrator
* @return the table handler
* @throws PException
*/</span>
<span class="kd">public</span> <span class="nc">PegasusTableInterface</span> <span class="nf">openTable</span><span class="o">(</span><span class="nc">String</span> <span class="n">tableName</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">PException</span><span class="o">;</span>
</code></pre></div></div>
<p>注:</p>
<ul>
<li>如果网络超时或者表不存在,都会抛出异常。</li>
</ul>
<p>使用示例:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nc">PegasusTableInterface</span> <span class="n">table</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">openTable</span><span class="o">(</span><span class="n">tableName</span><span class="o">);</span>
</code></pre></div></div>
<p>PegasusTableInterface中同时提供了同步和异步的API。</p>
<p>同步API与PegasusClientInterface基本一致