blob: b57a8809acaf0bd247293e8b29342f26ba04457d [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pegasus | Single Atomic</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>Single Atomic | Pegasus</title>
<meta name="generator" content="Jekyll v4.3.3" />
<meta property="og:title" content="Single Atomic" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="从 v1.10.0 版本开始,Pegasus 支持了单行原子操作。 这里的单行是指同一 HashKey 下的所有数据。" />
<meta property="og:description" content="从 v1.10.0 版本开始,Pegasus 支持了单行原子操作。 这里的单行是指同一 HashKey 下的所有数据。" />
<meta property="og:site_name" content="Pegasus" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2024-04-22T13:02:52+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Single Atomic" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","dateModified":"2024-04-22T13:02:52+00:00","datePublished":"2024-04-22T13:02:52+00:00","description":"从 v1.10.0 版本开始,Pegasus 支持了单行原子操作。 这里的单行是指同一 HashKey 下的所有数据。","headline":"Single Atomic","mainEntityOfPage":{"@type":"WebPage","@id":"/api/single-atomic"},"url":"/api/single-atomic"}</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="">
Java 客户端
</a>
</li>
<li>
<a href="/zh/clients/cpp-client"
class="">
C++ 客户端
</a>
</li>
<li>
<a href="https://github.com/apache/incubator-pegasus/tree/master/go-client"
class="">
Golang 客户端
</a>
</li>
<li>
<a href="/zh/clients/python-client"
class="">
Python 客户端
</a>
</li>
<li>
<a href="/zh/clients/node-client"
class="">
NodeJS 客户端
</a>
</li>
<li>
<a href="/zh/clients/scala-client"
class="">
Scala 客户端
</a>
</li>
</ul>
<p class="menu-label">生态工具</p>
<ul class="menu-list">
<li>
<a href="/zh/docs/tools/shell"
class="">
Pegasus Shell 工具
</a>
</li>
<li>
<a href="https://github.com/pegasus-kv/admin-cli"
class="">
集群管理命令行
</a>
</li>
<li>
<a href="https://github.com/pegasus-kv/pegic"
class="">
数据访问命令行
</a>
</li>
</ul>
<p class="menu-label">用户接口</p>
<ul class="menu-list">
<li>
<a href="/zh/api/ttl"
class="">
TTL
</a>
</li>
<li>
<a href="/zh/api/single-atomic"
class="is-active">
单行原子操作
</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="">
Replica Server 白名单
</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=" /api/single-atomic"><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 ">
Java 客户端
</a>
<a href="/zh/clients/cpp-client"
class="navbar-item ">
C++ 客户端
</a>
<a href="https://github.com/apache/incubator-pegasus/tree/master/go-client"
class="navbar-item ">
Golang 客户端
</a>
<a href="/zh/clients/python-client"
class="navbar-item ">
Python 客户端
</a>
<a href="/zh/clients/node-client"
class="navbar-item ">
NodeJS 客户端
</a>
<a href="/zh/clients/scala-client"
class="navbar-item ">
Scala 客户端
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
生态工具
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/docs/tools/shell"
class="navbar-item ">
Pegasus Shell 工具
</a>
<a href="https://github.com/pegasus-kv/admin-cli"
class="navbar-item ">
集群管理命令行
</a>
<a href="https://github.com/pegasus-kv/pegic"
class="navbar-item ">
数据访问命令行
</a>
</div>
</div>
<!--dropdown-->
<div class="navbar-item has-dropdown is-hoverable">
<a href=""
class="navbar-link ">
<span>
用户接口
</span>
</a>
<div class="navbar-dropdown">
<a href="/zh/api/ttl"
class="navbar-item ">
TTL
</a>
<a href="/zh/api/single-atomic"
class="navbar-item is-active">
单行原子操作
</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 ">
Replica Server 白名单
</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=" /api/single-atomic"><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">单行原子操作</p>
</div>
</section>
<section class="section" style="padding-top: 2rem;">
<div class="content">
<p>从 v1.10.0 版本开始,Pegasus 支持了单行原子操作。</p>
<blockquote>
<p>这里的<strong>单行</strong>是指同一 HashKey 下的所有数据。</p>
</blockquote>
<h1 id="原理">原理</h1>
<p>Pegasus 的数据分布策略采用了固定 Hash 分片,同一个 HashKey 的数据总是存储在同一个 Partition 中,即在单节点内的同一 Replica 中。同时,同一个 Replica 的写操作在 server 端总是串行执行的。因此对于同一 HashKey 下的数据操作,可以很方便地实现原子语义。</p>
<p>对于写操作,譬如 <a href="/zh/clients/java-client#multiset">multiSet</a><a href="/zh/clients/java-client#multidel">multiDel</a>,单个操作中对多个 SortKey 同时 <em>set</em> 或者 <em>delete</em>,原子语义很容易理解,要么同时成功,要么同时失败,所以这两个操作属于单行原子操作。</p>
<p>这里重点介绍另一类操作:<strong>先读后写,并且写操作依赖读的结果</strong>。这类操作的特点就是:它们是<strong>非幂等</strong>的,即同一个操作如果重复执行,造成的结果(包括数据实际的更新情况、返回给用户的结果)可能是不同的。原子增减和 CAS 操作都属于这类。 Pegasus 能保证这类操作的原子性和一致性,因为:</p>
<ul>
<li>同一个 HashKey 的数据总是存储在同一个 Replica 中</li>
<li>同一个 Replica 的写操作在 server 端总是串行执行的</li>
<li>同一个操作保证执行且只会执行一次,即使发生数据迁移、宕机恢复等情况</li>
</ul>
<p>由于非幂等特性,这类操作会和 Pegasus 的另外一些特性冲突,譬如 <a href="/zh/administration/duplication">跨机房同步</a>。所以我们在 1.10.0 版本中还提供了一个配置项,用于配置集群是否允许非幂等操作,如果配置为 false,则所有非幂等操作都会返回<code class="language-plaintext highlighter-rouge">ERR_OPERATION_DISABLED</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[replication]</span>
<span class="py">allow_non_idempotent_write</span> <span class="p">=</span> <span class="s">false</span>
</code></pre></div></div>
<h1 id="原子增减">原子增减</h1>
<p>虽然 Pegasus 的 value 不支持 schema,但是我们依然提供了原子增减操作,类似 Redis 的 <a href="https://redis.io/commands/incr/">incr命令</a>,Pegasus 接口参见 <a href="/zh/clients/java-client#incr">incr</a></p>
<h2 id="语义解释">语义解释</h2>
<ul>
<li>由于存储引擎 RocksDB 只能存储字节串类型的 value,所以在 <code class="language-plaintext highlighter-rouge">incr()</code> 的时候会先将读取出 value 字节串,转换为 int64 类型(转换方式就是简单的 String-to-Int),譬如字节串<code class="language-plaintext highlighter-rouge">"12345"</code>就会转换为数字 <code class="language-plaintext highlighter-rouge">12345</code>。完成<code class="language-plaintext highlighter-rouge">incr()</code>操作后,得到的结果会重新转换为字节串,然后存储为新值</li>
<li>字节串转换为 int64 时可能出错,譬如不是合法的数字、超过 int64 的范围等,都会返回失败</li>
<li>如果原 value 不存在,则认为原始值为 0,再执行<code class="language-plaintext highlighter-rouge">incr()</code>操作</li>
<li>操作数<code class="language-plaintext highlighter-rouge">increment</code>可以为正数也可以为负数,所以一个<code class="language-plaintext highlighter-rouge">incr()</code>接口就可以实现原子增或者原子减</li>
<li>TTL:如果原 value 存在,则新值和原值的 TTL 保持一致;如果原 value 不存在,则新值在存储时不设 TTL</li>
</ul>
<h1 id="cas-操作">CAS 操作</h1>
<p>另一类很有用的原子操作就是 CAS(Compare-And-Swap)操作。基于 CAS 操作,可以实现很多高级的并发特性,譬如分布式锁。</p>
<p>Pegasus 提供了 <em>check_and_set</em> 的 CAS 操作,其语义就是:根据 HashKey 的某一个 SortKey 的 value 是否满足某种条件,来决定是否修改另一个 SortKey 的值。将用于判断条件的 SortKey 称之为<code class="language-plaintext highlighter-rouge">CheckSortKey</code>,将用于设置值的 SortKey 称之为<code class="language-plaintext highlighter-rouge">SetSortKey</code>。对应地,<code class="language-plaintext highlighter-rouge">CheckSortKey</code> 的 value 称之为<code class="language-plaintext highlighter-rouge">CheckValue</code><code class="language-plaintext highlighter-rouge">SetSortKey</code> 要设置的 value 称之为<code class="language-plaintext highlighter-rouge">SetValue</code>。参见 <a href="/zh/clients/java-client#checkandset">checkAndSet</a>,以及其扩展版本 <a href="/zh/clients/java-client#checkandmutate">checkAndMutate</a><a href="/zh/clients/java-client#compareexchange">compareExchange</a></p>
<h2 id="语义解释-1">语义解释</h2>
<ul>
<li>只有当<code class="language-plaintext highlighter-rouge">CheckValue</code>满足指定的条件时,才会设置<code class="language-plaintext highlighter-rouge">SetSortKey</code>的值</li>
<li>需要满足的条件类型通过<code class="language-plaintext highlighter-rouge">CheckType</code>指定,有的<code class="language-plaintext highlighter-rouge">CheckType</code>还需要指定操作数<code class="language-plaintext highlighter-rouge">CheckOperand</code>。目前支持的类型包括:
<ul>
<li>判断<code class="language-plaintext highlighter-rouge">CheckValue</code><em>存在性</em>:是否存在、是否为空字节串等</li>
<li>字节串比较:将<code class="language-plaintext highlighter-rouge">CheckValue</code><code class="language-plaintext highlighter-rouge">CheckOperand</code>按照字节序比较,看是否满足<code class="language-plaintext highlighter-rouge">&lt;</code><code class="language-plaintext highlighter-rouge">&lt;=</code><code class="language-plaintext highlighter-rouge">==</code><code class="language-plaintext highlighter-rouge">&gt;=</code><code class="language-plaintext highlighter-rouge">&gt;=</code>关系</li>
<li>数字比较:类似于 <a href="#原子增减">incr操作</a>,先将<code class="language-plaintext highlighter-rouge">CheckValue</code>转换为int64,再与<code class="language-plaintext highlighter-rouge">CheckOperand</code>比较,看是否满足<code class="language-plaintext highlighter-rouge">&lt;</code><code class="language-plaintext highlighter-rouge">&lt;=</code><code class="language-plaintext highlighter-rouge">==</code><code class="language-plaintext highlighter-rouge">&gt;=</code><code class="language-plaintext highlighter-rouge">&gt;=</code>关系</li>
</ul>
</li>
<li><code class="language-plaintext highlighter-rouge">CheckSortKey</code><code class="language-plaintext highlighter-rouge">SetSortKey</code>可以相同,如果相同,就是先判断旧值是否满足条件,满足的话就设置为新值</li>
<li>可以通过选项<code class="language-plaintext highlighter-rouge">CheckAndSetOptions.returnCheckValue</code>指定返回<code class="language-plaintext highlighter-rouge">CheckValue</code>的值</li>
<li>可以通过选项<code class="language-plaintext highlighter-rouge">CheckAndSetOptions.setValueTTLSeconds</code>指定<code class="language-plaintext highlighter-rouge">SetValue</code>的 TTL</li>
</ul>
<p>为了方便使用,Pegasus Java Client 还提供了 <em>compare_exchange</em> 接口:当 HashKey 的某个 SortKey 的 value 按照字节串比较等于用户指定的<code class="language-plaintext highlighter-rouge">ExpectedValue</code>时,就将其 value 更新为用户指定的<code class="language-plaintext highlighter-rouge">DesiredValue</code>。从语义上来看,<em>compare_exchange</em> 是 Compare-And-Swap 的一种特殊形式。接口参见 <a href="/zh/clients/java-client#compareexchange">compareExchange</a></p>
<p><em>compare_exchange</em> 其实是 <em>check_and_set</em> 的特化版本,即:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">CheckSortKey</code><code class="language-plaintext highlighter-rouge">SetSortKey</code>相同</li>
<li><code class="language-plaintext highlighter-rouge">CheckType</code><code class="language-plaintext highlighter-rouge">CT_VALUE_BYTES_EQUAL</code></li>
</ul>
</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 &copy; 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="#原理">原理</a></li>
<li><a href="#原子增减">原子增减</a>
<ul>
<li><a href="#语义解释">语义解释</a></li>
</ul>
</li>
<li><a href="#cas-操作">CAS 操作</a>
<ul>
<li><a href="#语义解释-1">语义解释</a></li>
</ul>
</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>