| <!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:51:44+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:51:44+00:00","datePublished":"2023-11-23T14:51:44+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/python2-client" |
| class=""> |
| Python2客户端 |
| </a> |
| </li> |
| |
| <li> |
| <a href="/zh/clients/python3-client" |
| class=""> |
| Python3客户端 |
| </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/python2-client" |
| class="navbar-item "> |
| Python2客户端 |
| </a> |
| |
| <a href="/zh/clients/python3-client" |
| class="navbar-item "> |
| Python3客户端 |
| </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"><dependency></span> |
| <span class="nt"><groupId></span>com.xiaomi.infra<span class="nt"></groupId></span> |
| <span class="nt"><artifactId></span>pegasus-client<span class="nt"></artifactId></span> |
| <span class="nt"><version></span>2.0.0<span class="nt"></version></span> |
| <span class="nt"></dependency></span> |
| </code></pre></div></div> |
| |
| <p><strong>注:2.0.0版本仅适用于服务端PegasusServer >= 2.0, 如果服务端版本较低,请使用下面的版本</strong></p> |
| <div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span> |
| <span class="nt"><groupId></span>com.xiaomi.infra<span class="nt"></groupId></span> |
| <span class="nt"><artifactId></span>pegasus-client<span class="nt"></artifactId></span> |
| <span class="nt"><version></span>1.11.10-thrift-0.11.0-inlined<span class="nt"></version></span> |
| <span class="nt"></dependency></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="nc">PException</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]>></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 <= 0 means no limit. default value is 100. |
| * @param maxFetchSize max size of k-v pairs to be fetched. |
| * max_fetch_size <= 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"><</span><span class="kt">byte</span><span class="o">[]></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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"><</span><span class="kt">byte</span><span class="o">[]></span> <span class="n">sortKeys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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 <= 0 means no limit. default value is 100 |
| * @param maxFetchSize max size of kv pairs to be fetched. |
| * maxFetchSize <= 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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]>>></span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">HashKeyData</span><span class="o">></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]>>></span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="nc">PException</span><span class="o">,</span> <span class="nc">HashKeyData</span><span class="o">>></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必须>=0, 当<0时会抛出PException异常。</li> |
| <li>返回值:无。</li> |
| <li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL<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"><</span><span class="nc">SetItem</span><span class="o">></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"><</span><span class="nc">SetItem</span><span class="o">></span> <span class="n">items</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">PException</span><span class="o">></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 <sortkey,value> 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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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必须>=0, 当<0时会抛出PException异常。 |
| <ul> |
| <li>Values是Pair列表,Pair的第一个元素是SortKey,第二个元素为value。</li> |
| </ul> |
| </li> |
| <li>返回值:无。</li> |
| <li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL<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"><</span><span class="nc">HashKeyData</span><span class="o">></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"><</span><span class="nc">HashKeyData</span><span class="o">></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必须>=0, 当<0时会抛出PException异常。</li> |
| <li>返回值:无。</li> |
| <li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL<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"><</span><span class="nc">HashKeyData</span><span class="o">></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"><</span><span class="nc">PException</span><span class="o">></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"><</span><span class="nc">HashKeyData</span><span class="o">></span> <span class="n">items</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">PException</span><span class="o">></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必须>=0, 当<0时会抛出PException异常。</li> |
| <li>传出参数:Results。该变量需由调用者创建;Results[i]中存放Items[i]对应的结果;如果Results[i]不为null(PException已设置),表示对Items[i]的请求失败。</li> |
| </ul> |
| </li> |
| <li>返回值:请求成功的个数。</li> |
| <li>异常:如果出现异常,譬如参数错误、表名不存在、TTL<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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">PException</span><span class="o">></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"><</span><span class="kt">byte</span><span class="o">[]></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]>>></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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="nc">List</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]>>></span> <span class="n">keys</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">PException</span><span class="o">></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 > 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 > 0,则将TTL设置为新值。</li> |
| <li>如果参数ttlSeconds == -1,则清理掉TTL,即新值不再设置TTL。</li> |
| <li>如果参数ttlSeconds < -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 < 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 <= 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 >= 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 > 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 < 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 <= 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 >= 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 > 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必须>=0,0表示不设置TTL限制,当<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<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 > 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 |
| * <p>Future return: On success: return CheckAndMutateResult. On failure: a throwable, which |
| * is an instance of PException |
| * <p>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"><</span><span class="nc">CheckAndMutateResult</span><span class="o">></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. |
| * <p> |
| * - 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. |
| * <p> |
| * 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必须>=0,0表示不设置TTL限制,当TTL<0时将抛出PException异常。</li> |
| </ul> |
| </li> |
| <li>返回值:CompareExchangeResult,包括: |
| <ul> |
| <li>setSucceed:是否set成功,如果旧数据不存在,则set失败。</li> |
| <li>actualValue:如果set失败,返回该value的实际值;null表示不存在。</li> |
| </ul> |
| </li> |
| <li>异常:如果出现异常,譬如网络错误、超时错误、服务端错误、TTL<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 <= 0 means no limit. default value is 100. |
| * @param maxFetchSize max size of k-v pairs to be fetched. |
| * max_fetch_size <= 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"><</span><span class="kt">byte</span><span class="o">[]></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"><</span><span class="kt">byte</span><span class="o">[]></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 > 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<PegasusScannerInterface> 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基本一致,区别在于:不用指定tableName参数;可以单独指定超时时间。</p> |
| |
| <p>同时,openTable提供了warmup功能,用于解决表的第一次rpc调用过慢的问题,具体可参考最佳实践一节。</p> |
| |
| <h3 id="基于future的异步api">基于Future的异步API</h3> |
| <p>异步API使用Future模式,具体来说是使用的 io.netty.util.concurrent.Future (参见 https://netty.io/4.1/api/index.html )。每个异步接口的返回值都是一个Future<T>,其中T是该操作返回结果的类型。Future具有如下特性:</p> |
| <ul> |
| <li>可以通过 addListener() 方法设置一个或者多个Listener,即异步回调函数。回调函数会在操作完成时被调用;如果在add时操作已经完成,回调函数就会被立即调用;回调函数被调用的顺序与添加的顺序一致。</li> |
| <li>可以通过 await() 方法等待操作完成。但是注意的是await()方法只能保证操作完成以及下面的三个方法可用,并不能保证回调函数已经被执行。</li> |
| <li>在操作完成后,可以通过 isSuccess() 方法判断操作是否成功;如果成功,可以通过 getNow() 方法获取结果;如果失败,可以通过 cause() 方法获取异常。</li> |
| </ul> |
| |
| <p><strong>注意</strong>:第一次调用一个表的异步API的时候,函数返回之前可能会有一些额外延迟(典型地10ms左右),这是因为第一次调用时需要从meta-server获取表的信息和路由信息。</p> |
| |
| <p>一个典型的异步使用样例:</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 获取Table实例</span> |
| <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> |
| |
| <span class="c1">// 发起异步调用</span> |
| <span class="nc">Future</span><span class="o"><</span><span class="nc">Boolean</span><span class="o">></span> <span class="n">future</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="na">asyncExist</span><span class="o">(</span><span class="n">hashKey</span><span class="o">,</span> <span class="n">sortKey</span><span class="o">,</span> <span class="mi">0</span><span class="o">);</span> |
| |
| <span class="c1">// 设置回调函数</span> |
| <span class="n">future</span><span class="o">.</span><span class="na">addListener</span><span class="o">(</span> |
| <span class="k">new</span> <span class="nf">ExistListener</span><span class="o">()</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Boolean</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> |
| <span class="k">if</span> <span class="o">(</span><span class="n">future</span><span class="o">.</span><span class="na">isSuccess</span><span class="o">())</span> <span class="o">{</span> |
| <span class="nc">Boolean</span> <span class="n">result</span> <span class="o">=</span> <span class="n">future</span><span class="o">.</span><span class="na">getNow</span><span class="o">();</span> |
| <span class="o">}</span> |
| <span class="k">else</span> <span class="o">{</span> |
| <span class="n">future</span><span class="o">.</span><span class="na">cause</span><span class="o">().</span><span class="na">printStackTrace</span><span class="o">();</span> |
| <span class="o">}</span> |
| <span class="o">}</span> |
| <span class="o">}</span> |
| <span class="o">);</span> |
| |
| <span class="c1">// 等待操作完成</span> |
| <span class="n">future</span><span class="o">.</span><span class="na">await</span><span class="o">();</span> |
| </code></pre></div></div> |
| |
| <h2 id="pegasustableinterface接口">PegasusTableInterface接口</h2> |
| |
| <h3 id="asyncget">asyncGet</h3> |
| <p>异步读单行数据。</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">interface</span> <span class="nc">GetListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncGet future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * Get value for a specific (hashKey, sortKey) pair, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or empty, means hash key is "". |
| * @param sortKey all keys under the same hashKey will be sorted by sortKey |
| * if null or empty, means sort key is "". |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: the got value |
| * On failure: a throwable, which is an instance of PException |
| * |
| * Thread safety: |
| * The api is thread safe. |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]></span> <span class="nf">asyncGet</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">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数:需传入HashKey、SortKey、timeout。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<byte[]>。</li> |
| </ul> |
| |
| <h3 id="asyncmultiget">asyncMultiGet</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">static</span> <span class="kd">class</span> <span class="nc">MultiGetResult</span> <span class="o">{</span> |
| <span class="cm">/** |
| * return value for multiGet |
| * @param allFetched true if all data on the server are fetched; false if only partial data are fetched. |
| * @param values the got values. If sortKey in the input sortKeys is not found, it won't be in values. |
| * The output values are ordered by the sortKey. |
| */</span> |
| <span class="kd">public</span> <span class="kt">boolean</span> <span class="n">allFetched</span><span class="o">;</span> |
| <span class="kd">public</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">values</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="kd">public</span> <span class="kd">static</span> <span class="kd">interface</span> <span class="nc">MultiGetListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetResult</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncMultiGet future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetResult</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * get multiple key-values under the same hashKey, async version |
| * @param hashKey used to decide which partition the key may exist |
| * should not be null or empty. |
| * @param sortKeys try to get values of sortKeys under the hashKey |
| * if null or empty, try to get all (sortKey,value) pairs under hashKey |
| * @param maxFetchCount max count of kv pairs to be fetched |
| * maxFetchCount <= 0 means no limit. default value is 100 |
| * @param maxFetchSize max size of kv pairs to be fetched. |
| * maxFetchSize <= 0 means no limit. default value is 1000000. |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: An object of type MultiGetResult |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetResult</span><span class="o">></span> <span class="nf">asyncMultiGet</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"><</span><span class="kt">byte</span><span class="o">[]></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="kt">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| <span class="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetResult</span><span class="o">></span> <span class="nf">asyncMultiGet</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"><</span><span class="kt">byte</span><span class="o">[]></span> <span class="n">sortKeys</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>提供了两个版本的接口,其中第一个接口可以指定maxFetchCount和maxFetchSize。</li> |
| <li>参数:需传入HashKey、SortKeys、timeout;选择性传入maxFetchCount、maxFetchSize。 |
| <ul> |
| <li>SortKeys如果非空,则只读取指定的数据;SortKeys如果为空,则表示读取该HashKey下的所有数据。</li> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| <li>maxFetchCount和maxFetchSize用于限制读取的数据量,maxFetchCount表示最多读取的数据条数,maxFetchSize表示最多读取的数据字节数,两者任一达到限制就停止读取。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<MultiGetResult>。 |
| <ul> |
| <li>allFetched:如果用户指定了maxFetchCount或者maxFetchSize,单次查询可能只获取到部分结果。如果所有满足条件的数据都已经获取到,则设置为true;否则设置为false。</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <p>asyncMultiGet还有另外一个版本的接口,可以支持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="cm">/** |
| * get multiple key-values under the same hashKey with sortKey range limited, async version |
| * @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 <= 0 means no limit. default value is 100 |
| * @param maxFetchSize max size of kv pairs to be fetched. |
| * maxFetchSize <= 0 means no limit. default value is 1000000. |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: An object of type MultiGetResult |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetResult</span><span class="o">></span> <span class="nf">asyncMultiGet</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="kt">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| <span class="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetResult</span><span class="o">></span> <span class="nf">asyncMultiGet</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">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数使用同<a href="#multiget">multiGet</a></li> |
| </ul> |
| |
| <h3 id="asyncset">asyncSet</h3> |
| <p>异步写单行数据。</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">interface</span> <span class="nc">SetListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncSet future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * Set value for a specific (hashKey, sortKey) pair, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or empty, means hash key is "". |
| * @param sortKey all keys under the same hashKey will be sorted by sortKey |
| * if null or empty, means sort key is "". |
| * @param value should not be null |
| * @param ttlSeconds time to live in seconds |
| * 0 means no ttl, default value is 0 |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: no return |
| * On failure: a throwable, which is an instance of PException |
| * |
| * Thread safety: |
| * The api is thread safe. |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="nf">asyncSet</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">ttlSeconds</span><span class="o">,</span> <span class="kt">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| <span class="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="nf">asyncSet</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">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>提供了两个版本的接口,其中第一个接口可以指定TTL时间。</li> |
| <li>参数:需传入HashKey、SortKey、Value、timeout;选择性传入TTL。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| <li>ttlSeconds是数据的TTL时间,单位为秒。TTL必须>=0, 0表示不设置TTL时间,当TTL<0时将抛出PException异常。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Void>。</li> |
| </ul> |
| |
| <h3 id="asyncmultiset">asyncMultiSet</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">static</span> <span class="kd">interface</span> <span class="nc">MultiSetListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncMultiSet future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * Set key-values for a specific hashKey, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or empty, means hash key is "". |
| * @param values all (sortKey, value) pairs |
| * should not be null or empty |
| * @param ttlSeconds time to live in seconds |
| * 0 means no ttl, default value is 0 |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: no return |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="nf">asyncMultiSet</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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">values</span><span class="o">,</span> <span class="kt">int</span> <span class="n">ttlSeconds</span><span class="o">,</span> <span class="kt">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| <span class="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="nf">asyncMultiSet</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"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">values</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>提供了两个版本的接口,其中第一个接口可以指定TTL时间。</li> |
| <li>参数:需传入HashKey、Values、timeout;选择性传入ttlSeconds。 |
| <ul> |
| <li>Values是Pair列表,Pair的第一个元素是SortKey,第二个元素为value。</li> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| <li>ttlSeconds是数据的TTL时间,单位为秒。TTL必须>=0, 0表示不设置TTL时间,当TTL<0时将抛出PException异常。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Void>。</li> |
| </ul> |
| |
| <h3 id="asyncdel">asyncDel</h3> |
| <p>异步删单行数据。</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">interface</span> <span class="nc">DelListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncDel future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * delete value for a specific (hashKey, sortKey) pair, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or empty, means hash key is "". |
| * @param sortKey all keys under the same hashKey will be sorted by sortKey |
| * if null or empty, means sort key is "". |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: no return |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="nf">asyncDel</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">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数:需传入HashKey、SortKey、timeout。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Void>。</li> |
| </ul> |
| |
| <h3 id="asyncmultidel">asyncMultiDel</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">static</span> <span class="kd">interface</span> <span class="nc">MultiDelListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncMultiDel future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * delete mutiple values for a specific hashKey, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or empty, means hash key is "". |
| * @param sortKeys all the sortKeys need to be deleted |
| * should not be null or empty |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: no return |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Void</span><span class="o">></span> <span class="nf">asyncMultiDel</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"><</span><span class="kt">byte</span><span class="o">[]></span> <span class="n">sortKeys</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>参数:需传入HashKey、SortKeys、timeout。 |
| <ul> |
| <li>SortKeys不允许为空,如果不知道该HashKey下面有哪些SortKey,可以通过multiGetSortKeys方法获取。</li> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Void>。</li> |
| </ul> |
| |
| <h3 id="asyncincr">asyncIncr</h3> |
| <p>原子增(减)操作。<a href="#incr">incr</a>的异步版本。</p> |
| |
| <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static interface IncrListener extends GenericFutureListener<Future<Long>> { |
| /** |
| * This function will be called when listened asyncIncr future is done. |
| * |
| * @param future the listened future |
| * @throws Exception throw exception if any error occurs. |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */ |
| @Override |
| public void operationComplete(Future<Long> future) throws Exception; |
| } |
| |
| /** |
| * atomically increment value by key, async version |
| * |
| * @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 timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * <p> |
| * Future return: |
| * On success: return new value. |
| * On failure: a throwable, which is an instance of PException |
| * <p> |
| * 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. |
| */ |
| public Future<Long> asyncIncr(byte[] hashKey, byte[] sortKey, long increment, int timeout/*ms*/); |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数和返回值:参见同步接口<a href="#incr">incr</a>。</li> |
| </ul> |
| |
| <h3 id="asynccheckandset">asyncCheckAndSet</h3> |
| <p>单HashKey数据的原子CAS操作。<a href="#checkandset">checkAndSet</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">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="kd">public</span> <span class="kd">static</span> <span class="kd">interface</span> <span class="nc">CheckAndSetListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">CheckAndSetResult</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncCheckAndSet future is done. |
| * |
| * @param future the listened future |
| * @throws Exception throw exception if any error occurs. |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">CheckAndSetResult</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * atomically check and set value by key, async version. |
| * if the check condition is satisfied, then apply to set value. |
| * |
| * @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. |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * <p> |
| * Future return: |
| * On success: return CheckAndSetResult. |
| * On failure: a throwable, which is an instance of PException |
| * <p> |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">CheckAndSetResult</span><span class="o">></span> <span class="nf">asyncCheckAndSet</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="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>参数和返回值:参见同步接口<a href="#checkandset">checkAndSet</a>。</li> |
| </ul> |
| |
| <h3 id="asynccompareexchange">asyncCompareExchange</h3> |
| <p>单HashKey数据的原子CAS操作。<a href="#compareexchange">compareExchange</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="kd">public</span> <span class="kd">static</span> <span class="kd">interface</span> <span class="nc">CompareExchangeListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">CompareExchangeResult</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncCompareExchange future is done. |
| * |
| * @param future the listened future |
| * @throws Exception throw exception if any error occurs. |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">CompareExchangeResult</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * atomically compare and exchange value by key, async version. |
| * <p> |
| * - 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. |
| * <p> |
| * this method is very like the C++ function in {https://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange}. |
| * |
| * @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. |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * <p> |
| * Future return: |
| * On success: return CompareExchangeResult. |
| * On failure: a throwable, which is an instance of PException |
| * <p> |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">CompareExchangeResult</span><span class="o">></span> <span class="nf">asyncCompareExchange</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="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>参数和返回值:参见同步接口<a href="#compareexchange">compareExchange</a>。</li> |
| </ul> |
| |
| <h3 id="asyncttl">asyncTTL</h3> |
| <p>异步获取单行数据的TTL时间,即该数据还能存活多久,单位为秒。</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">interface</span> <span class="nc">TTLListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncTTL future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * get TTL value for a specific (hashKey, sortKey) pair, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or empty, means hash key is "". |
| * @param sortKey all keys under the same hashKey will be sorted by sortKey |
| * if null or empty, means sort key is "". |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: ttl time in seconds; -1 if no ttl set; -2 if not exist. |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="nf">asyncTTL</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">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数:需传入HashKey、SortKey、timeout。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Integer>。 |
| <ul> |
| <li>返回结果为TTL时间,单位为秒。如果该数据没有设置TTL,返回-1;如果该数据不存在,返回-2。</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h3 id="asyncexist">asyncExist</h3> |
| <p>异步检查数据是否存在。</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">interface</span> <span class="nc">ExistListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Boolean</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncExist future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Boolean</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * Check value existence for a specific (hashKey, sortKey) pair of current table, async version |
| * @param hashKey used to decide which partition the key may exist |
| * if null or length == 0, means hash key is "". |
| * @param sortKey all keys under the same hashKey will be sorted by sortKey |
| * if null or length == 0, means sort key is "". |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 0, it is a timeout value for current op, |
| * else the timeout value in the configuration file will be used. |
| * |
| * @return A future for current op. |
| * |
| * Future return: |
| * On success: true if exist, false if not exist |
| * On failure: a throwable, which is an instance of PException |
| * |
| * Thread safety: |
| * The api is thread safe. |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Boolean</span><span class="o">></span> <span class="nf">asyncExist</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">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数:需传入HashKey、SortKey、timeout。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Boolean>。 |
| <ul> |
| <li>返回结果是个布尔值。如果存在返回true,否则返回false。</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h3 id="asyncsortkeycount">asyncSortKeyCount</h3> |
| <p>异步获取某个HashKey下所有SortKey的个数。</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">interface</span> <span class="nc">SortKeyCountListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Long</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncSortKeyCount future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">Long</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * Count the sortkeys for a specific hashKey, async version |
| * @param hashKey used to decide which partition the key may exist |
| * should not be null or empty |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: the count result for the hashKey |
| * On failure: a throwable, which is an instance of PException |
| * |
| * Thread safety: |
| * The api is thread safe. |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Long</span><span class="o">></span> <span class="nf">asyncSortKeyCount</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">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>参数:需传入HashKey、timeout。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<Long>。 |
| <ul> |
| <li>返回结果为HashKey下所有SortKey的个数。</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h3 id="asyncmultigetsortkeys">asyncMultiGetSortKeys</h3> |
| <p>异步获取某个HashKey下SortKey列表。</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">MultiGetSortKeysResult</span> <span class="o">{</span> |
| <span class="cm">/** |
| * return value for multiGetSortkeys |
| * @param allFetched true if all data on the server are fetched; false if only partial data are fetched. |
| * @param keys the got keys. |
| * The output keys are in order. |
| */</span> |
| <span class="kd">public</span> <span class="kt">boolean</span> <span class="n">allFetched</span><span class="o">;</span> |
| <span class="kd">public</span> <span class="nc">List</span><span class="o"><</span><span class="kt">byte</span><span class="o">[]></span> <span class="n">keys</span><span class="o">;</span> |
| <span class="o">};</span> |
| |
| <span class="kd">public</span> <span class="kd">static</span> <span class="kd">interface</span> <span class="nc">MultiGetSortKeysListener</span> <span class="kd">extends</span> <span class="nc">GenericFutureListener</span><span class="o"><</span><span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetSortKeysResult</span><span class="o">>></span> <span class="o">{</span> |
| <span class="cm">/** |
| * This function will be called when listened asyncMultiGetSortKeys future is done. |
| * @param future the listened future |
| * @throws Exception |
| * |
| * Notice: User shouldn't do any operations that may block or time-consuming |
| */</span> |
| <span class="nd">@Override</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">operationComplete</span><span class="o">(</span><span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetSortKeysResult</span><span class="o">></span> <span class="n">future</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="cm">/** |
| * get all the sortKeys for the same hashKey |
| * @param hashKey used to decide which partition the key may exist |
| * should not be null or empty. |
| * @param maxFetchCount max count of kv pairs to be fetched |
| * maxFetchCount <= 0 means no limit. default value is 100 |
| * @param maxFetchSize max size of kv pairs to be fetched. |
| * maxFetchSize <= 0 means no limit. default value is 1000000. |
| * @param timeout how long will the operation timeout in milliseconds. |
| * if timeout > 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 |
| * |
| * Future return: |
| * On success: An object of type MultiGetSortKeysResult |
| * On failure: a throwable, which is an instance of PException |
| * |
| * 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="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetSortKeysResult</span><span class="o">></span> <span class="nf">asyncMultiGetSortKeys</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="kt">int</span> <span class="n">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| <span class="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">MultiGetSortKeysResult</span><span class="o">></span> <span class="nf">asyncMultiGetSortKeys</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">timeout</span><span class="cm">/*ms*/</span><span class="o">);</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>提供了两个版本的接口,其中第一个接口可以指定maxFetchCount和maxFetchSize。</li> |
| <li>参数:需传入HashKey、timeout;选择性传入maxFetchCount、maxFetchSize。 |
| <ul> |
| <li>timeout单位为毫秒,如果<=0,表示使用配置文件中的默认超时。</li> |
| <li>maxFetchCount和maxFetchSize用于限制读取的数据量,maxFetchCount表示最多读取的数据条数,maxFetchSize表示最多读取的数据字节数,两者任一达到限制就停止读取。</li> |
| </ul> |
| </li> |
| <li>返回值:Future<MultiGetSortKeysResult>。 |
| <ul> |
| <li>allFetched:如果用户指定了maxFetchCount或者maxFetchSize,单次查询可能只获取到部分结果。如果所有满足条件的数据都已经获取到,则设置为true;否则设置为false。</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h2 id="pegasusscannerinterface接口">PegasusScannerInterface接口</h2> |
| |
| <h3 id="next">next</h3> |
| <p>在scan操作时,同步获取下一条数据。</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/** |
| * Get the next item. |
| * @return item like <<hashKey, sortKey>, value>; null returned if scan completed. |
| * @throws PException |
| */</span> |
| <span class="kd">public</span> <span class="nc">Pair</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>,</span> <span class="kt">byte</span><span class="o">[]></span> <span class="nf">next</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>返回值:Pair<Pair<byte[], byte[]>, byte[]>。 |
| <ul> |
| <li>下一条kv-pair;若scan操作完成,则返回null。</li> |
| </ul> |
| </li> |
| </ul> |
| |
| <h3 id="asyncnext">asyncNext</h3> |
| <p>在scan操作时,异步获取下一条数据。</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/** |
| * Get the next item asynchronously. |
| * @return A future for current op. |
| * |
| * Future return: |
| * On success: if scan haven't reach the end then return the kv-pair, else return null. |
| * On failure: a throwable, which is an instance of PException. |
| */</span> |
| <span class="kd">public</span> <span class="nc">Future</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>,</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="nf">asyncNext</span><span class="o">();</span> |
| </code></pre></div></div> |
| <p>注:</p> |
| <ul> |
| <li>返回值:Future<Pair<Pair<byte[], byte[]>, byte[]>>。</li> |
| <li>在scan未扫描完成之前,会返回需要的kv-pair;当scan扫描完成之后,返回null。</li> |
| </ul> |
| |
| <h2 id="常见异常">常见异常</h2> |
| |
| <h3 id="err_object_not_found">ERR_OBJECT_NOT_FOUND</h3> |
| <p>表名不存在。可能原因:</p> |
| <ul> |
| <li>集群中没有建表。</li> |
| <li>访问了错误的集群。在日志中搜索<code class="language-plaintext highlighter-rouge">meta_servers</code>,看集群的配置是否正确。</li> |
| <li>表名拼写错误。检查代码中的表名是否正确;在日志中搜索<code class="language-plaintext highlighter-rouge">initialize table handler</code>,看表名是否正确。</li> |
| </ul> |
| |
| <h3 id="err_timeout">ERR_TIMEOUT</h3> |
| <p>访问超时。可能原因:</p> |
| <ul> |
| <li>网络连接出错。</li> |
| <li>读写延迟超过了超时时间。</li> |
| <li>服务出现抖动。</li> |
| </ul> |
| |
| <h3 id="err_session_reset">ERR_SESSION_RESET</h3> |
| <p>服务端状态出错。可能原因:</p> |
| <ul> |
| <li>服务端正在做replica迁移,发生了状态切换。</li> |
| <li>服务端有节点宕机,造成备份数不够,为了保证数据一致性,服务降级,变得不可用。</li> |
| <li>如果是客户端初始化时得到该错误,可能是由于 meta 配置不正确,请检查配置</li> |
| </ul> |
| |
| <h3 id="err_busy">ERR_BUSY</h3> |
| <p>服务端流控达到限制。原因是:</p> |
| <ul> |
| <li>集群服务端对表设置了<a href="/zh/administration/throttling#服务端流控">表级写流量控制</a>。</li> |
| <li>此时该表的瞬时流量(在这1秒内的写入操作数)达到了阈值,触发了reject流控操作,返回<code class="language-plaintext highlighter-rouge">ERR_BUSY</code>错误码。</li> |
| </ul> |
| |
| <h1 id="最佳实践">最佳实践</h1> |
| |
| <h2 id="流量控制">流量控制</h2> |
| <p>经常有业务有集中灌数据的场景,灌数据的过程可能是单机的也可能是分布式的,譬如使用Spark处理后将数据写入Pegasus中。</p> |
| |
| <p>如果不做流控,很可能产生很高的QPS峰值写,对Pegasus系统造成较大压力:</p> |
| <ul> |
| <li>写QPS太大,会影响读性能,造成读操作延迟上升;</li> |
| <li>写QPS太大,可能会造成集群无法承受压力而停止服务;</li> |
| </ul> |
| |
| <p>因此,强烈建议业务方在灌数据的时候对写QPS进行流量控制。</p> |
| |
| <p>客户端流控的思路就是:</p> |
| <ul> |
| <li>首先定好总的QPS限制是多少(譬如10000/s),有多少个并发的客户端访问线程(譬如50个),然后计算出每个线程的QPS限制(譬如10000/50=200)。</li> |
| <li>对于单个客户端线程,通过流控工具将QPS限制在期望的范围内。如果超过了QPS限制,就采用简单的sleep方式来等待。我们提供了一个流控工具类<a href="https://github.com/XiaoMi/pegasus-java-client/blob/thrift-0.11.0-inlined/src/main/java/com/xiaomi/infra/pegasus/tools/FlowController.java">com.xiaomi.infra.pegasus.tools.FlowController</a>,把计算QPS和执行sleep的逻辑封装起来,方便用户使用。</li> |
| </ul> |
| |
| <p>FlowController用法:</p> |
| <ul> |
| <li>构造函数接受一个QPS参数,用于指定流量限制,譬如单线程QPS只允许200/s,就传入200;</li> |
| <li>用户在每次需要执行写操作之前调用cntl.getToken()方法,该方法产生两种可能: |
| <ul> |
| <li>如果当前未达到流量控制,则无阻塞直接返回,继续执行后面的写操作;</li> |
| <li>如果当前已经达到流量限制,则该方法会阻塞(sleep)一段时间才返回,以达到控制流量的效果。</li> |
| </ul> |
| </li> |
| <li>该工具尽量配合同步接口使用,对于异步接口可能效果没那么好。</li> |
| </ul> |
| |
| <p>使用方法很简单:</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">FlowController</span> <span class="n">cntl</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FlowController</span><span class="o">(</span><span class="n">qps</span><span class="o">);</span> |
| <span class="k">while</span> <span class="o">(</span><span class="kc">true</span><span class="o">)</span> <span class="o">{</span> |
| <span class="c1">// call getToken before operation</span> |
| <span class="n">cntl</span><span class="o">.</span><span class="na">getToken</span><span class="o">();</span> |
| <span class="n">client</span><span class="o">.</span><span class="na">set</span><span class="o">(...);</span> |
| <span class="o">}</span> |
| <span class="n">cntl</span><span class="o">.</span><span class="na">stop</span><span class="o">();</span> |
| </code></pre></div></div> |
| |
| <p>在分布式灌数据的场景下,用户可以先确定分布式的Task并发数,然后通过<code class="language-plaintext highlighter-rouge">总QPS限制 / Task并发数</code>,得到单个Task的QPS限制,再使用FlowController进行控制。</p> |
| |
| <h2 id="分页查询">分页查询</h2> |
| |
| <p>类似实现网页列表的分页功能。 |
| 典型地,一个HashKey下有很多SortKey,一页只显示固定数量的SortKey,下一页时再显示接下来的固定数量的SortKey。</p> |
| |
| <p>分页查询在Pegasus下有多种实现方式:</p> |
| |
| <ol> |
| <li>一次性获取HaskKey下的全部数据,在业务端缓存下来,由业务端自己实现分页逻辑。</li> |
| <li><strong>顺序分页</strong>:可以使用<a href="#multiget">multiGet()</a>和<a href="#getscanner">getScanner()</a>方法,这两者都支持SortKey的范围查询</li> |
| <li><strong>逆序分页</strong>:请使用<a href="#multiget">multiGet()</a>方法,其支持SortKey的逆序查询</li> |
| </ol> |
| |
| <h3 id="顺序分页">顺序分页</h3> |
| |
| <p>使用 <code class="language-plaintext highlighter-rouge">getScanner</code> 接口:</p> |
| |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ScanOptions</span> <span class="n">options</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ScanOptions</span><span class="o">();</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">startInclusive</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">batchSize</span> <span class="o">=</span> <span class="mi">20</span><span class="o">;</span> <span class="c1">// 限制每页的大小为 20</span> |
| <span class="kt">byte</span><span class="o">[]</span> <span class="n">startSortKey</span> <span class="o">=</span> <span class="kc">null</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="kc">null</span><span class="o">;</span> |
| <span class="nc">PegasusScannerInterface</span> <span class="n">scanner</span> <span class="o">=</span> |
| <span class="n">client</span><span class="o">.</span><span class="na">getScanner</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="n">hashKey</span><span class="o">,</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="n">stopSortKey</span><span class="o">,</span> <span class="n">options</span><span class="o">);</span> |
| |
| <span class="c1">// 同步方式获取</span> |
| <span class="nc">Pair</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>,</span> <span class="kt">byte</span><span class="o">[]></span> <span class="n">item</span><span class="o">;</span> |
| <span class="k">while</span> <span class="o">((</span><span class="n">item</span> <span class="o">=</span> <span class="n">scanner</span><span class="o">.</span><span class="na">next</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> |
| <span class="c1">// ... //</span> |
| <span class="o">}</span> |
| |
| <span class="c1">// 异步方式获取</span> |
| <span class="nc">Future</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>,</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">item</span><span class="o">;</span> |
| <span class="k">while</span> <span class="o">(</span><span class="kc">true</span><span class="o">)</span> <span class="o">{</span> |
| <span class="n">item</span> <span class="o">=</span> <span class="n">scanner</span><span class="o">.</span><span class="na">asyncNext</span><span class="o">();</span> |
| <span class="k">try</span> <span class="o">{</span> |
| <span class="nc">Pair</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>,</span> <span class="kt">byte</span><span class="o">[]></span> <span class="n">pair</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="na">get</span><span class="o">();</span> |
| <span class="k">if</span> <span class="o">(</span><span class="n">pair</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> |
| <span class="k">break</span><span class="o">;</span> |
| <span class="o">}</span> |
| <span class="c1">// ... //</span> |
| <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> |
| <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span> |
| <span class="o">}</span> |
| <span class="o">}</span> |
| </code></pre></div></div> |
| |
| <p>如果你使用 <code class="language-plaintext highlighter-rouge">multiGet</code>,在 <code class="language-plaintext highlighter-rouge">MultiGetOptions</code> 中还需设置 <code class="language-plaintext highlighter-rouge">maxFetchCount</code>,限制每页条数:</p> |
| |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 查第一页</span> |
| <span class="nc">MultiGetOptions</span> <span class="n">options</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MultiGetOptions</span><span class="o">();</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">startInclusive</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> |
| <span class="kt">int</span> <span class="n">maxFetchCount</span> <span class="o">=</span> <span class="mi">20</span><span class="o">;</span> <span class="c1">// 限制每页的大小为 20</span> |
| <span class="kt">int</span> <span class="n">maxFetchSize</span> <span class="o">=</span> <span class="mi">20000</span><span class="o">;</span> <span class="c1">// 限制每页的总字节数为 20000</span> |
| <span class="kt">byte</span><span class="o">[]</span> <span class="n">startSortKey</span> <span class="o">=</span> <span class="kc">null</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="kc">null</span><span class="o">;</span> |
| <span class="nc">List</span><span class="o"><</span><span class="nc">Pair</span><span class="o"><</span><span class="kt">byte</span><span class="o">[],</span> <span class="kt">byte</span><span class="o">[]>></span> <span class="n">values</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span> |
| <span class="kt">boolean</span> <span class="n">allFetched</span> <span class="o">=</span> |
| <span class="n">client</span><span class="o">.</span><span class="na">multiGet</span><span class="o">(</span> |
| <span class="n">tableName</span><span class="o">,</span> <span class="n">hashKey</span><span class="o">,</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="n">stopSortKey</span><span class="o">,</span> <span class="n">options</span><span class="o">,</span> |
| <span class="n">maxFetchCount</span><span class="o">,</span> <span class="n">maxFetchSize</span><span class="o">,</span> <span class="n">values</span><span class="o">);</span> |
| <span class="k">if</span> <span class="o">(</span><span class="n">allFetched</span><span class="o">)</span> <span class="o">{</span> |
| <span class="k">return</span><span class="o">;</span> |
| <span class="o">}</span> |
| |
| <span class="c1">// ... //</span> |
| |
| <span class="c1">// 查下一页</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">startInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> |
| <span class="n">startSortKey</span> <span class="o">=</span> <span class="n">values</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">values</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">);</span> <span class="c1">// 以上一页的最后(最大)一个值作为下一页查询的开始</span> |
| <span class="n">stopSortKey</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> |
| <span class="n">allFetched</span> <span class="o">=</span> |
| <span class="n">client</span><span class="o">.</span><span class="na">multiGet</span><span class="o">(</span> |
| <span class="n">tableName</span><span class="o">,</span> <span class="n">hashKey</span><span class="o">,</span> <span class="n">startSortKey</span><span class="o">,</span> <span class="n">stopSortKey</span><span class="o">,</span> <span class="n">options</span><span class="o">,</span> |
| <span class="n">maxFetchCount</span><span class="o">,</span> <span class="n">maxFetchSize</span><span class="o">,</span> <span class="n">values</span><span class="o">);</span> |
| <span class="k">if</span> <span class="o">(</span><span class="n">allFetched</span><span class="o">)</span> <span class="o">{</span> |
| <span class="k">return</span><span class="o">;</span> |
| <span class="o">}</span> |
| </code></pre></div></div> |
| |
| <h3 id="逆序分页">逆序分页</h3> |
| |
| <p>逆序分页需要使用<code class="language-plaintext highlighter-rouge">multiGet</code>接口,并在选项中设置<code class="language-plaintext highlighter-rouge">reverse=true</code>。</p> |
| |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">MultiGetOptions</span> <span class="n">options</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MultiGetOptions</span><span class="o">();</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">startInclusive</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">stopInclusive</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span> |
| <span class="n">options</span><span class="o">.</span><span class="na">reverse</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span> |
| </code></pre></div></div> |
| |
| <h2 id="数据序列化">数据序列化</h2> |
| |
| <p>Pegasus的key和value都是原始的字节串(Java中就是byte[]),而用户存储数据一般用struct或者class。因此,在将数据存储到Pegasus中时,需要将用户数据转化为字节串,这就是<strong>序列化</strong>;在从Pegasus中读取数据时,又需要将字节串转化为用户的数据结构,这就是<strong>反序列化</strong>。序列化和反序列化通常都是成对出现了,后面我们只描述序列化。</p> |
| |
| <p>通常序列化有这些方式:</p> |
| <ul> |
| <li>json:好处是数据可读性好;坏处是比较占空间。不推荐。</li> |
| <li>thrift:提供了多种Compact协议,常见的有binary协议。但是推荐用tcompact协议,因为这种协议的压缩率更高。</li> |
| <li>protobuf:与thrift类似,推荐序列化为binary格式。</li> |
| </ul> |
| |
| <p>对于Thrift结构,使用tcompact协议进行序列化的样例:</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kn">import</span> <span class="nn">org.apache.thrift.TSerializer</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">org.apache.thrift.protocol.TCompactProtocol</span><span class="o">;</span> |
| |
| <span class="nc">TSerializer</span> <span class="n">serializer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TSerializer</span><span class="o">(</span><span class="k">new</span> <span class="nc">TCompactProtocol</span><span class="o">.</span><span class="na">Factory</span><span class="o">());</span> |
| <span class="kt">byte</span><span class="o">[]</span> <span class="n">bytes</span> <span class="o">=</span> <span class="n">serializer</span><span class="o">.</span><span class="na">serialize</span><span class="o">(</span><span class="n">data</span><span class="o">);</span> |
| </code></pre></div></div> |
| |
| <h2 id="数据压缩">数据压缩</h2> |
| |
| <p>对于value较大(>=2kb)的业务,我们推荐在客户端使用<a href="https://github.com/facebook/zstd">facebook/Zstandard</a>压缩算法(简称 Zstd)对数据进行压缩,以减少value的数据长度,提升Pegasus的服务稳定性和读写性能。Zstd算法在压缩比和压缩速率上取得较好的平衡,适合通用场景。</p> |
| |
| <p>从Java Client 1.11.3版本开始,我们提供了Zstd压缩工具类<a href="https://github.com/XiaoMi/pegasus-java-client/blob/thrift-0.11.0-inlined/src/main/java/com/xiaomi/infra/pegasus/tools/ZstdWrapper.java">com.xiaomi.infra.pegasus.tools.ZstdWrapper</a>,方便用户实现压缩功能。</p> |
| |
| <p>使用示例:</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kt">byte</span><span class="o">[]</span> <span class="n">value</span> <span class="o">=</span> <span class="s">"xxx"</span><span class="o">;</span> |
| |
| <span class="c1">// write the record into pegasus</span> |
| <span class="n">table</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"h"</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(),</span> <span class="s">"s"</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(),</span> <span class="nc">ZstdWrapper</span><span class="o">.</span><span class="na">compress</span><span class="o">(</span><span class="n">value</span><span class="o">),</span> <span class="mi">1000</span><span class="o">);</span> |
| |
| <span class="c1">// read the record from pegasus</span> |
| <span class="kt">byte</span><span class="o">[]</span> <span class="n">compressedBuf</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"h"</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(),</span> <span class="s">"s"</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(),</span> <span class="mi">1000</span><span class="o">);</span> |
| |
| <span class="c1">// decompress the value</span> |
| <span class="kt">byte</span><span class="o">[]</span> <span class="n">orginalValue</span> <span class="o">=</span> <span class="nc">ZstdWrapper</span><span class="o">.</span><span class="na">decompress</span><span class="o">(</span><span class="n">compressedBuf</span><span class="o">);</span> |
| </code></pre></div></div> |
| |
| <p>也可以参考测试用例代码 <a href="https://github.com/XiaoMi/pegasus-java-client/blob/thrift-0.11.0-inlined/src/test/java/com/xiaomi/infra/pegasus/tools/TestZstdWrapper.java">TestZstdWrapper.java</a>。</p> |
| |
| <p>以上两个优化 <a href="#数据序列化">数据序列化</a> 和 <a href="#数据压缩">数据压缩</a> 可以在客户端同时使用,都是用客户端的CPU换取Pegasus集群的稳定性和读写性能。在通常情况下这都是值得的。</p> |
| |
| <p>有时候,业务方在开始使用Pegasus的时候,没有采用客户端压缩,但是在使用一段时间后,发现单条数据的value比较大,希望能通过压缩的办法改进性能。可以分两步:</p> |
| <ul> |
| <li><a href="#评估压缩收益">评估压缩收益</a>:评估通过客户端压缩是否能够获得足够好的压缩率。</li> |
| <li><a href="#使用兼容性压缩">使用兼容性压缩</a>:升级业务端使用Pegasus Java客户端的逻辑,增加客户端压缩支持,同时兼容原来未压缩的数据。</li> |
| </ul> |
| |
| <h3 id="评估压缩收益">评估压缩收益</h3> |
| |
| <p>对于已经存在的表,原来没有采用客户端压缩,如何快速评估采用客户端压缩后有多大收益?</p> |
| |
| <p>原料:</p> |
| <ul> |
| <li>业务集群:user_cluster,meta配置地址为<code class="language-plaintext highlighter-rouge">${user_cluster_meta_list}</code>,其中用户表为user_table。</li> |
| <li>测试集群:test_cluster,meta配置地址为<code class="language-plaintext highlighter-rouge">${test_cluster_meta_list}</code>。</li> |
| <li><a href="/zh/overview/shell">Shell工具</a>:使用1.11.3及以上版本;修改配置文件<code class="language-plaintext highlighter-rouge">src/shell/config.ini</code>,添加访问test_cluster集群的配置项。</li> |
| <li><a href="#java客户端工具">Java客户端工具</a>:使用1.11.4及以上版本;修改配置文件<code class="language-plaintext highlighter-rouge">pegasus.properties</code>,设置<code class="language-plaintext highlighter-rouge">meta_servers = ${test_cluster_meta_list}</code>。</li> |
| </ul> |
| |
| <p>步骤:</p> |
| <ul> |
| <li>使用Shell工具的create命令,在test_cluster集群中新建测试表user_table_no_compress和user_table_zstd_compress: |
| <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./run.sh shell --cluster ${test_cluster_meta_list} |
| >>> create user_table_no_compress -p 8 -r 3 |
| >>> create user_table_zstd_compress -p 8 -r 3 |
| </code></pre></div> </div> |
| </li> |
| <li>使用Shell工具的copy_data命令,将业务集群的user_table表的部分数据复制到测试集群的user_table_no_compress表中(在复制足够条数后通过Ctrl-C中断执行): |
| <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./run.sh shell --cluster ${user_cluster_meta_list} |
| >>> use user_table |
| >>> copy_data -c test_cluster -a user_table_no_compress |
| </code></pre></div> </div> |
| </li> |
| <li>使用Java客户端工具的copy_data命令,将测试集群user_table_no_compress表的数据复制到user_table_zstd_compress表中,并设置数据写出时采用zstd压缩: |
| <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./PegasusCli file://./pegasus.properties user_table_no_compress \ |
| copy_data file://./pegasus.properties user_table_zstd_compress none zstd |
| </code></pre></div> </div> |
| </li> |
| <li>使用Shell工具的count_data命令,分别统计两个测试表的数据大小,然后计算压缩率: |
| <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./run.sh shell --cluster ${test_cluster_meta_list} |
| >>> use user_table_no_compress |
| >>> count_data -a |
| >>> use user_table_zstd_compress |
| >>> count_data -a |
| </code></pre></div> </div> |
| </li> |
| </ul> |
| |
| <h3 id="使用兼容性压缩">使用兼容性压缩</h3> |
| |
| <p>业务表原来已经有未压缩的数据,如果应用了客户端压缩,写入新的已压缩的数据,但是hashKey和sortKey保持不变,就会出现未压缩数据和已压缩数据<strong>混合存在</strong>的情况:有的value存储的是未压缩的数据,有的value存储的是已压缩的数据。</p> |
| |
| <p>这就要求业务端在读数据的时候<strong>保证兼容性</strong>:既能读取未压缩的数据,又能读取已压缩的数据。</p> |
| |
| <p>基于<strong>未压缩的数据采用zstd进行解压缩时基本都会失败</strong>这一事实,业务端读取的逻辑可以这样:</p> |
| <ul> |
| <li>首先,尝试将客户端读到的value数据进行解压缩,如果成功,则说明是已压缩的数据。</li> |
| <li>如果上一步解压缩失败,则说明读到的是未压缩的数据,不需要解压。</li> |
| </ul> |
| |
| <p>示例代码:</p> |
| <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">// decompress the value</span> |
| <span class="kt">byte</span><span class="o">[]</span> <span class="n">decompressedValue</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> |
| <span class="k">try</span> <span class="o">{</span> |
| <span class="n">decompressedValue</span> <span class="o">=</span> <span class="nc">ZstdWrapper</span><span class="o">.</span><span class="na">decompress</span><span class="o">(</span><span class="n">value</span><span class="o">);</span> |
| <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">PException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> |
| <span class="c1">// decompress fail</span> |
| <span class="n">decompressedValue</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span> |
| <span class="o">}</span> |
| </code></pre></div></div> |
| |
| <p>与此同时,可以使用后台工具将未压缩数据逐渐替换掉为已压缩数据,并在替换过程中保证数据的一致性:扫描表,逐条读取数据,如果数据是未压缩的,则将其转换为已压缩的,使用check_and_set原子操作进行数据替换。</p> |
| |
| <h2 id="客户端连接预热warm-up">客户端连接预热(Warm Up)</h2> |
| |
| <p>我们提供了提供了客户端连接预热(warmup)功能,在进行openTable时提前拉取路由表并建立连接。这样可以避免在该表的第一次rpc调用时,由于执行上述步骤而导致的该次rpc调用过慢的问题。</p> |
| |
| <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> |
| |
| <h1 id="常见问题">常见问题</h1> |
| |
| |
| </div> |
| </section> |
| <footer class="footer"> |
| <div class="container"> |
| <div class="content is-small has-text-centered"> |
| <div style="margin-bottom: 20px;"> |
| <a href="http://incubator.apache.org"> |
| <img src="/assets/images/egg-logo.png" |
| width="15%" |
| alt="Apache Incubator"/> |
| </a> |
| </div> |
| Copyright © 2023 <a href="http://www.apache.org">The Apache Software Foundation</a>. |
| Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version |
| 2.0</a>. |
| <br><br> |
| |
| Apache Pegasus is an effort undergoing incubation at The Apache Software Foundation (ASF), |
| sponsored by the Apache Incubator. Incubation is required of all newly accepted projects |
| until a further review indicates that the infrastructure, communications, and decision making process |
| have stabilized in a manner consistent with other successful ASF projects. While incubation status is |
| not necessarily a reflection of the completeness or stability of the code, it does indicate that the |
| project has yet to be fully endorsed by the ASF. |
| |
| <br><br> |
| Apache Pegasus, Pegasus, Apache, the Apache feather logo, and the Apache Pegasus project logo are either |
| registered trademarks or trademarks of The Apache Software Foundation in the United States and other |
| countries. |
| </div> |
| </div> |
| </footer> |
| </div> |
| |
| <!-- right panel --> |
| <div class="dashboard-panel is-small is-scrollable is-hidden-mobile"> |
| <p class="menu-label"> |
| <span class="icon"> |
| <i class="fa fa-bars" aria-hidden="true"></i> |
| </span> |
| 本页导航 |
| </p> |
| <ul class="menu-list"> |
| <li><a href="#获取java客户端">获取Java客户端</a></li> |
| <li><a href="#客户端配置">客户端配置</a> |
| <ul> |
| <li><a href="#文件配置">文件配置</a></li> |
| <li><a href="#参数传递">参数传递</a></li> |
| </ul> |
| </li> |
| <li><a href="#接口定义">接口定义</a> |
| <ul> |
| <li><a href="#创建client实例">创建Client实例</a> |
| <ul> |
| <li><a href="#单例">单例</a></li> |
| <li><a href="#非单例">非单例</a></li> |
| </ul> |
| </li> |
| <li><a href="#pegasusclientinterface接口">PegasusClientInterface接口</a> |
| <ul> |
| <li><a href="#get">get</a></li> |
| <li><a href="#batchget">batchGet</a></li> |
| <li><a href="#batchget2">batchGet2</a></li> |
| <li><a href="#multiget">multiGet</a></li> |
| <li><a href="#batchmultiget">batchMultiGet</a></li> |
| <li><a href="#batchmultiget2">batchMultiGet2</a></li> |
| <li><a href="#set">set</a></li> |
| <li><a href="#batchset">batchSet</a></li> |
| <li><a href="#batchset2">batchSet2</a></li> |
| <li><a href="#multiset">multiSet</a></li> |
| <li><a href="#batchmultiset">batchMultiSet</a></li> |
| <li><a href="#batchmultiset2">batchMultiSet2</a></li> |
| <li><a href="#del">del</a></li> |
| <li><a href="#batchdel">batchDel</a></li> |
| <li><a href="#batchdel2">batchDel2</a></li> |
| <li><a href="#multidel">multiDel</a></li> |
| <li><a href="#batchmultidel">batchMultiDel</a></li> |
| <li><a href="#batchmultidel2">batchMultiDel2</a></li> |
| <li><a href="#delrange">delRange</a></li> |
| <li><a href="#incr">incr</a></li> |
| <li><a href="#checkandset">checkAndSet</a></li> |
| <li><a href="#checkandmutate">checkAndMutate</a></li> |
| <li><a href="#compareexchange">compareExchange</a></li> |
| <li><a href="#ttl">ttl</a></li> |
| <li><a href="#exist">exist</a></li> |
| <li><a href="#sortkeycount">sortKeyCount</a></li> |
| <li><a href="#multigetsortkeys">multiGetSortKeys</a></li> |
| <li><a href="#getscanner">getScanner</a></li> |
| <li><a href="#getunorderedscanner">getUnorderedScanner</a></li> |
| </ul> |
| </li> |
| <li><a href="#创建table实例">创建Table实例</a> |
| <ul> |
| <li><a href="#基于future的异步api">基于Future的异步API</a></li> |
| </ul> |
| </li> |
| <li><a href="#pegasustableinterface接口">PegasusTableInterface接口</a> |
| <ul> |
| <li><a href="#asyncget">asyncGet</a></li> |
| <li><a href="#asyncmultiget">asyncMultiGet</a></li> |
| <li><a href="#asyncset">asyncSet</a></li> |
| <li><a href="#asyncmultiset">asyncMultiSet</a></li> |
| <li><a href="#asyncdel">asyncDel</a></li> |
| <li><a href="#asyncmultidel">asyncMultiDel</a></li> |
| <li><a href="#asyncincr">asyncIncr</a></li> |
| <li><a href="#asynccheckandset">asyncCheckAndSet</a></li> |
| <li><a href="#asynccompareexchange">asyncCompareExchange</a></li> |
| <li><a href="#asyncttl">asyncTTL</a></li> |
| <li><a href="#asyncexist">asyncExist</a></li> |
| <li><a href="#asyncsortkeycount">asyncSortKeyCount</a></li> |
| <li><a href="#asyncmultigetsortkeys">asyncMultiGetSortKeys</a></li> |
| </ul> |
| </li> |
| <li><a href="#pegasusscannerinterface接口">PegasusScannerInterface接口</a> |
| <ul> |
| <li><a href="#next">next</a></li> |
| <li><a href="#asyncnext">asyncNext</a></li> |
| </ul> |
| </li> |
| <li><a href="#常见异常">常见异常</a> |
| <ul> |
| <li><a href="#err_object_not_found">ERR_OBJECT_NOT_FOUND</a></li> |
| <li><a href="#err_timeout">ERR_TIMEOUT</a></li> |
| <li><a href="#err_session_reset">ERR_SESSION_RESET</a></li> |
| <li><a href="#err_busy">ERR_BUSY</a></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li><a href="#最佳实践">最佳实践</a> |
| <ul> |
| <li><a href="#流量控制">流量控制</a></li> |
| <li><a href="#分页查询">分页查询</a> |
| <ul> |
| <li><a href="#顺序分页">顺序分页</a></li> |
| <li><a href="#逆序分页">逆序分页</a></li> |
| </ul> |
| </li> |
| <li><a href="#数据序列化">数据序列化</a></li> |
| <li><a href="#数据压缩">数据压缩</a> |
| <ul> |
| <li><a href="#评估压缩收益">评估压缩收益</a></li> |
| <li><a href="#使用兼容性压缩">使用兼容性压缩</a></li> |
| </ul> |
| </li> |
| <li><a href="#客户端连接预热warm-up">客户端连接预热(Warm Up)</a></li> |
| </ul> |
| </li> |
| <li><a href="#常见问题">常见问题</a></li> |
| </ul> |
| |
| </div> |
| </div> |
| |
| <script src="/assets/js/app.js" type="text/javascript"></script> |
| <script> |
| docsearch({ |
| container: '#docsearch', |
| appId: 'QRN30RBW0S', |
| indexName: 'pegasus-apache', |
| apiKey: 'd3a3252fa344359766707a106c4ed88f', |
| debug: true |
| }); |
| </script> |
| |
| </body> |
| |
| </html> |