Skip to content

Commit

Permalink
修复 string 类命令的引用问题
Browse files Browse the repository at this point in the history
  • Loading branch information
huangzworks committed Mar 31, 2012
1 parent f2c079f commit 57d80be
Show file tree
Hide file tree
Showing 8 changed files with 14 additions and 17 deletions.
2 changes: 1 addition & 1 deletion string/decr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ DECR

本操作的值限制在 64 位(bit)有符号数字表示之内。

关于递增(increment) / 递减(decrement)操作的更多信息,请参见 `INCR`_ 命令。
关于递增(increment) / 递减(decrement)操作的更多信息,请参见 :ref:`INCR` 命令。

**可用版本:**
>= 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion string/decrby.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ DECRBY

本操作的值限制在 64 位(bit)有符号数字表示之内。

关于更多递增(increment) / 递减(decrement)操作的更多信息,请参见 `INCR`_ 命令。
关于更多递增(increment) / 递减(decrement)操作的更多信息,请参见 :ref:`INCR` 命令。

**可用版本:**
>= 1.0.0
Expand Down
4 changes: 2 additions & 2 deletions string/getset.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ GETSET
模式
--------

`GETSET`_ 可以和 `INCR`_ 组合使用,实现一个有原子性(atomic)复位操作的计数器(counter)。
`GETSET`_ 可以和 :ref:`INCR` 组合使用,实现一个有原子性(atomic)复位操作的计数器(counter)。

举例来说,每次当某个事件发生时,进程可能对一个名为 ``mycount`` 的 ``key`` 调用 `INCR`_ 操作,通常我们还要在一个原子时间内同时完成获得计数器的值和将计数器值复位为 ``0`` 两个操作。
举例来说,每次当某个事件发生时,进程可能对一个名为 ``mycount`` 的 ``key`` 调用 :ref:`INCR` 操作,通常我们还要在一个原子时间内同时完成获得计数器的值和将计数器值复位为 ``0`` 两个操作。

可以用命令 ``GETSET mycounter 0`` 来实现这一目标。

Expand Down
2 changes: 1 addition & 1 deletion string/incr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ INCR

可以用以下几种方式扩展这个简单的模式:

- 可以通过组合使用 `INCR`_ 和 :ref:`EXPIRE` ,来达到只在规定的生存时间内进行计数(counting)的目的。
- 可以通过组合使用 `INCR`_ 和 :ref:`expire` ,来达到只在规定的生存时间内进行计数(counting)的目的。
- 客户端可以通过使用 :ref:`GETSET` 命令原子性地获取计数器的当前值并将计数器清零,更多信息请参考 :ref:`GETSET` 命令。
- 使用其他自增/自减操作,比如 :ref:`DECR` 和 :ref:`INCRBY` ,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。

Expand Down
4 changes: 1 addition & 3 deletions string/incrby.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ INCRBY

本操作的值限制在 64 位(bit)有符号数字表示之内。

关于递增(increment) / 递减(decrement)操作的更多信息,参见 `INCR`_ 命令。
关于递增(increment) / 递减(decrement)操作的更多信息,参见 :ref:`INCR` 命令。

**可用版本:**
>= 1.0.0
Expand Down Expand Up @@ -55,5 +55,3 @@ INCRBY

redis> INCRBY book 200
(error) ERR value is not an integer or out of range


2 changes: 1 addition & 1 deletion string/mset.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ MSET

同时设置一个或多个 ``key-value`` 对。

如果某个给定 ``key`` 已经存在,那么 `MSET`_ 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 `MSETNX`_ 命令:它只会在所有给定 ``key`` 都不存在的情况下进行设置操作。
如果某个给定 ``key`` 已经存在,那么 `MSET`_ 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 :ref:`MSETNX` 命令:它只会在所有给定 ``key`` 都不存在的情况下进行设置操作。

`MSET`_ 是一个原子性(atomic)操作,所有给定 ``key`` 都会在同一时间内被设置,某些给定 ``key`` 被更新而另一些给定 ``key`` 没有改变的情况,不可能发生。

Expand Down
2 changes: 1 addition & 1 deletion string/setbit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ SETBIT

``offset`` 参数必须大于或等于 ``0`` ,小于 2^32 (bit 映射被限制在 512 MB 之内)。

.. warning:: 对使用大的 ``offset`` 的 `SETBIT`_\ 操作来说,内存分配可能造成 Redis 服务器被阻塞。具体参考 `SETRANGE`_\ 命令,warning(警告)部分。
.. warning:: 对使用大的 ``offset`` 的 `SETBIT`_ 操作来说,内存分配可能造成 Redis 服务器被阻塞。具体参考 :ref:`SETRANGE`_ 命令,warning(警告)部分。

**可用版本:**
>= 2.2.0
Expand Down
13 changes: 6 additions & 7 deletions string/setnx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ SETNX
redis> GET job # 没有被覆盖
"programmer"

模式:将SETNX用于加锁(locking)
模式:将 SETNX 用于加锁(locking)
----------------------------------------

.. warning:: 已经证实这个加锁算法带有竞争条件,在特定情况下会造成错误,请不要使用这个加锁算法,具体请参考 `http://huangz.iteye.com/blog/1381538 <http://huangz.iteye.com/blog/1381538>`_ 。
Expand All @@ -57,7 +57,7 @@ SETNX
但是,当有多个客户端同时检测一个锁是否过期并尝试释放它的时候,我们不能简单粗暴地删除死锁的 ``key`` ,再用 `SETNX`_ 上锁,因为这时竞争条件(race condition)已经形成了:

* C1 和 C2 读取 ``lock.foo`` 并检查时间戳, `SETNX`_ 都返回 ``0`` ,因为它已经被 C3 锁上了,但 C3 在上锁之后就崩溃(crashed)了。
* C1 向 ``lock.foo`` 发送 :ref:`del` 命令。
* C1 向 ``lock.foo`` 发送 :ref:`DEL` 命令。
* C1 向 ``lock.foo`` 发送 `SETNX`_ 并成功。
* C2 向 ``lock.foo`` 发送 :ref:`del` 命令。
* C2 向 ``lock.foo`` 发送 `SETNX`_ 并成功。
Expand All @@ -67,15 +67,14 @@ SETNX

* C4 向 ``lock.foo`` 发送 `SETNX`_ 命令。
* 因为崩溃掉的 C3 还锁着 ``lock.foo`` ,所以 Redis 向 C4 返回 ``0`` 。
* C4 向 ``lock.foo`` 发送 `GET`_ 命令,查看 ``lock.foo`` 的锁是否过期。如果不,则休眠(sleep)一段时间,并在之后重试。
* C4 向 ``lock.foo`` 发送 :ref:`GET` 命令,查看 ``lock.foo`` 的锁是否过期。如果不,则休眠(sleep)一段时间,并在之后重试。
* 另一方面,如果 ``lock.foo`` 内的 unix 时间戳比当前时间戳老,C4 执行以下命令:

``GETSET lock.foo <current Unix timestamp + lock timeout + 1>``

* 因为 `GETSET`_ 的作用,C4 可以检查看 `GETSET`_ 的返回值,确定 ``lock.foo`` 之前储存的旧值仍是那个过期时间戳,如果是的话,那么 C4 获得锁。
* 如果其他客户端,比如 C5,比 C4 更快地执行了 `GETSET`_ 操作并获得锁,那么 C4 的 `GETSET`_ 操作返回的就是一个未过期的时间戳(C5 设置的时间戳)。C4 只好从第一步开始重试。
* 因为 :ref:`GETSET` 的作用,C4 可以检查看 :ref:`GETSET` 的返回值,确定 ``lock.foo`` 之前储存的旧值仍是那个过期时间戳,如果是的话,那么 C4 获得锁。
* 如果其他客户端,比如 C5,比 C4 更快地执行了 :ref:`GETSET` 操作并获得锁,那么 C4 的 :ref:`GETSET` 操作返回的就是一个未过期的时间戳(C5 设置的时间戳)。C4 只好从第一步开始重试。

| 注意,即便 C4 的 `GETSET`_ 操作对 ``key`` 进行了修改,这对未来也没什么影响。
| 注意,即便 C4 的 :ref:`GETSET` 操作对 ``key`` 进行了修改,这对未来也没什么影响。
.. warning:: 为了让这个加锁算法更健壮,获得锁的客户端应该常常检查过期时间以免锁因诸如 :ref:`DEL` 等命令的执行而被意外解开,因为客户端失败的情况非常复杂,不仅仅是崩溃这么简单,还可能是客户端因为某些操作被阻塞了相当长时间,紧接着 :ref:`DEL` 命令被尝试执行(但这时锁却在另外的客户端手上)。

0 comments on commit 57d80be

Please sign in to comment.