<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.eijux.com/index.php?action=history&amp;feed=atom&amp;title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89</id>
	<title>Redis：通信协议（protocol） - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.eijux.com/index.php?action=history&amp;feed=atom&amp;title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89"/>
	<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89&amp;action=history"/>
	<updated>2026-05-15T18:44:35Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.38.2</generator>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89&amp;diff=4711&amp;oldid=prev</id>
		<title>Eijux：​/* 内联命令 */</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89&amp;diff=4711&amp;oldid=prev"/>
		<updated>2021-11-02T18:39:19Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;内联命令&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2021年11月3日 (三) 02:39的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l225&quot;&gt;第225行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第225行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 内联命令 ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 内联命令 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; 当你需要和 Redis 服务器进行沟通，但又找不到 '''redis-cli'''，而手上只有 '''telnet''' 的时候，你可以通过 Redis 特别为这种情形而设的内联命令格式来发送命令。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;以下是一个客户端和服务器使用内联命令来进行交互的例子：&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: &amp;lt;syntaxhighlight lang=&quot;bash&quot; highlight=&quot;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;客户端： PING&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;服务器： +PONG&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/syntaxhighlight&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;以下另一个返回整数值的内联命令的例子：&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: &amp;lt;syntaxhighlight lang=&quot;bash&quot; highlight=&quot;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;客户端： EXISTS somekey&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;服务器： :0&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/syntaxhighlight&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; 因为没有了统一请求协议中的 “'''*'''” 项来声明参数的数量，所以在 telnet 会话输入命令的时候，必须使用空格来分割各个参数，服务器在接收到数据之后，会按空格对用户的输入进行分析（parse），并获取其中的命令参数。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;== 高性能 Redis 协议分析器 ==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; 尽管 Redis 的协议非常利于人类阅读，定义也很简单，但这个协议的实现性能仍然可以和二进制协议一样快。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; 因为 Redis 协议将数据的长度放在数据正文之前，所以程序无须像 JSON 那样，为了寻找某个特殊字符而扫描整个 payload，也无须对发送至服务器的 payload 进行转义（quote）。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;程序可以在对协议文本中的各个字符进行处理的同时，查找 CR 字符，并计算出批量回复或多条批量回复的长度，就像这样：&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: &amp;lt;syntaxhighlight lang=&quot;c&quot; highlight=&quot;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;#include &amp;lt;stdio.h&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;int main(void) {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    unsigned char *p = &quot;$123\r\n&quot;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    int len = 0;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    p++;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    while(*p != '\r') {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        len = (len*10)+(*p - '0');&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        p++;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    }&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    /* Now p points at '\r', and the len is in bulk_len. */&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    printf(&quot;%d\n&quot;, len);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    return 0;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/syntaxhighlight&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: 得到了批量回复或多条批量回复的长度之后，程序只需调用一次 read 函数，就可以将回复的正文数据全部读入到内存中，而无须对这些数据做任何的处理。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: 在回复最末尾的 CR 和 LF 不作处理，丢弃它们。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; Redis 协议的实现性能可以和二进制协议的实现性能相媲美，并且由于 Redis 协议的简单性，大部分高级语言都可以轻易地实现这个协议，这使得客户端软件的 bug 数量大大减少。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89&amp;diff=4710&amp;oldid=prev</id>
		<title>Eijux：​建立内容为“category:Redis  __TOC__  == 关于 ==  参考：[http://redis.io/topics/protocol http://redis.io/topics/protocol]  Redis 协议在以下三个目标之间进…”的新页面</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Redis%EF%BC%9A%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE%EF%BC%88protocol%EF%BC%89&amp;diff=4710&amp;oldid=prev"/>
		<updated>2021-11-02T18:34:17Z</updated>

		<summary type="html">&lt;p&gt;建立内容为“&lt;a href=&quot;/%E5%88%86%E7%B1%BB:Redis&quot; title=&quot;分类:Redis&quot;&gt;category:Redis&lt;/a&gt;  __TOC__  == 关于 ==  参考：[http://redis.io/topics/protocol http://redis.io/topics/protocol]  Redis 协议在以下三个目标之间进…”的新页面&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[category:Redis]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 参考：[http://redis.io/topics/protocol http://redis.io/topics/protocol]&lt;br /&gt;
&lt;br /&gt;
Redis 协议在以下三个目标之间进行折中：&lt;br /&gt;
# 易于实现&lt;br /&gt;
# 可以高效地被计算机分析（parse）&lt;br /&gt;
# 可以很容易地被人类读懂&lt;br /&gt;
&lt;br /&gt;
== 网络层 ==&lt;br /&gt;
 客户端和服务器通过 '''TCP 连接'''来进行数据交互，服务器默认的端口号为 '''6379'''。&lt;br /&gt;
 &lt;br /&gt;
 客户端和服务器发送的命令或数据一律以 '''\r\n''' （CRLF）结尾。&lt;br /&gt;
&lt;br /&gt;
== 请求 ==&lt;br /&gt;
 Redis 服务器接受命令以及命令的参数。&lt;br /&gt;
 &lt;br /&gt;
 服务器会在接到命令之后，对命令进行处理，并将命令的回复传送回客户端。&lt;br /&gt;
&lt;br /&gt;
== 新版统一请求协议 ==&lt;br /&gt;
 新版统一请求协议在 Redis 1.2 版本中引入，并最终在 Redis 2.0 版本成为 Redis 服务器通信的标准方式。&lt;br /&gt;
 &lt;br /&gt;
 你的 Redis 客户端应该按照这个新版协议来进行实现。&lt;br /&gt;
 &lt;br /&gt;
 在这个协议中，所有发送至 Redis 服务器的参数都是'''二进制安全'''（binary safe）的。&lt;br /&gt;
&lt;br /&gt;
以下是这个协议的一般形式：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
*&amp;lt;参数数量&amp;gt; CR LF&lt;br /&gt;
$&amp;lt;参数1 的字节数量&amp;gt; CR LF&lt;br /&gt;
&amp;lt;参数1 的数据&amp;gt; CR LF&lt;br /&gt;
...&lt;br /&gt;
$&amp;lt;参数N 的字节数量&amp;gt; CR LF&lt;br /&gt;
&amp;lt;参数N 的数据&amp;gt; CR LF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 命令本身也作为协议的其中一个参数来发送。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: 以下是一个命令协议的打印版本：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
*3&lt;br /&gt;
$3&lt;br /&gt;
SET&lt;br /&gt;
$5&lt;br /&gt;
mykey&lt;br /&gt;
$7&lt;br /&gt;
myvalue&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 这个命令的实际协议值如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 这种格式除了用作命令请求协议之外，也用在命令的回复协议中：这种只有一个参数的回复格式被称为'''批量回复'''（Bulk Reply）。&lt;br /&gt;
 &lt;br /&gt;
 统一协议请求原本是用在回复协议中，用于将列表的多个项返回给客户端的，这种回复格式被称为“'''多条批量回复'''”（Multi Bulk Reply）。&lt;br /&gt;
 &lt;br /&gt;
 一个多条批量回复以 '''*&amp;lt;argc&amp;gt;\r\n''' 为前缀，后跟多条不同的批量回复，其中 '''argc''' 为这些批量回复的数量。&lt;br /&gt;
&lt;br /&gt;
== 回复 ==&lt;br /&gt;
 Redis 命令会返回多种不同类型的回复。&lt;br /&gt;
&lt;br /&gt;
通过检查服务器发回数据的第一个字节，可以确定这个回复是什么类型：&lt;br /&gt;
# 状态回复（status reply）的第一个字节是 “'''+'''”。&lt;br /&gt;
# 错误回复（error reply）的第一个字节是 “'''-'''”。&lt;br /&gt;
# 整数回复（integer reply）的第一个字节是 “''':'''”。&lt;br /&gt;
# 批量回复（bulk reply）的第一个字节是 “'''$'''”。&lt;br /&gt;
# 多条批量回复（multi bulk reply）的第一个字节是 “'''*'''”。&lt;br /&gt;
&lt;br /&gt;
=== 状态回复 ===&lt;br /&gt;
 一个状态回复（或者单行回复，single line reply）是一段以 “'''+'''” 开始、“'''\r\n'''” 结尾的单行字符串。&lt;br /&gt;
&lt;br /&gt;
以下是一个状态回复的例子：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
+OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 客户端库应该返回 &amp;quot;'''+'''&amp;quot; 号之后的所有内容。&lt;br /&gt;
*: 比如在在上面的这个例子中，客户端就应该返回字符串 &amp;quot;OK&amp;quot; 。&lt;br /&gt;
* 状态回复通常由那些不需要返回数据的命令返回，这种回复不是二进制安全的，它也不能包含新行。&lt;br /&gt;
* 状态回复的额外开销非常少，只需要三个字节（开头的 &amp;quot;+&amp;quot; 和结尾的 CRLF）。&lt;br /&gt;
&lt;br /&gt;
=== 错误回复 ===&lt;br /&gt;
 错误回复和状态回复非常相似，它们之间的唯一区别是，错误回复的第一个字节是 “'''-'''”，而状态回复的第一个字节是 “'''+'''”。&lt;br /&gt;
 &lt;br /&gt;
 错误回复只在某些地方出现问题时发送。&lt;br /&gt;
     比如说，当用户对不正确的数据类型执行命令，或者执行一个不存在的命令，等等。&lt;br /&gt;
     &lt;br /&gt;
 一个客户端库应该在收到错误回复时产生一个异常。&lt;br /&gt;
&lt;br /&gt;
以下是两个错误回复的例子：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
-ERR unknown command 'foobar'&lt;br /&gt;
-WRONGTYPE Operation against a key holding the wrong kind of value&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 在 “'''-'''” 之后，直到遇到第一个空格或新行为止，这中间的内容表示所返回错误的类型。&lt;br /&gt;
* '''ERR''' 是一个通用错误，而 '''WRONGTYPE''' 则是一个更特定的错误。&lt;br /&gt;
** 一个客户端实现可以为不同类型的错误产生不同类型的异常，或者提供一种通用的方式，让调用者可以通过提供字符串形式的错误名来捕捉（trap）不同的错误。&lt;br /&gt;
**: 不过这些特性用得并不多，所以并不是特别重要，一个受限的（limited）客户端可以通过简单地返回一个逻辑假（false）来表示一个通用的错误条件。&lt;br /&gt;
&lt;br /&gt;
=== 整数回复 ===&lt;br /&gt;
 整数回复就是一个以 “''':'''” 开头， '''CRLF''' 结尾的字符串表示的整数。&lt;br /&gt;
&lt;br /&gt;
比如说，“:0\r\n”和“:1000\r\n”都是整数回复。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 返回整数回复的其中两个命令是 '''INCR''' 和 '''LASTSAVE'''。被返回的整数没有什么特殊的含义，INCR 返回键的一个自增后的整数值，而 LASTSAVE 则返回一个 UNIX 时间戳，返回值的唯一限制是这些数必须能够用 64 位有符号整数表示。&lt;br /&gt;
* 整数回复也被广泛地用于表示逻辑真和逻辑假： 比如 EXISTS 和 SISMEMBER 都用返回值 1 表示真，0 表示假。&lt;br /&gt;
* 其他一些命令，比如 SADD、SREM 和 SETNX，只在操作真正被执行了的时候，才返回 1，否则返回 0。&lt;br /&gt;
* 以下命令都返回整数回复：SETNX、DEL、EXISTS、INCR、INCRBY、DECR、DECRBY、DBSIZE、LASTSAVE、RENAMENX、MOVE、LLEN、SADD、SREM、SISMEMBER、SCARD。&lt;br /&gt;
&lt;br /&gt;
=== 批量回复 ===&lt;br /&gt;
 服务器使用批量回复来返回二进制安全的字符串，字符串的最大长度为 512 MB。&lt;br /&gt;
&lt;br /&gt;
服务器发送的内容中：&lt;br /&gt;
# 第一字节为 “'''$'''” 符号；&lt;br /&gt;
# 接下来跟着的是表示实际回复长度的数字值；&lt;br /&gt;
# 之后跟着一个 '''CRLF'''；&lt;br /&gt;
# 再后面跟着的是实际回复数据；&lt;br /&gt;
# 最末尾是另一个 '''CRLF'''；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: 对于如下的 GET 命令：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
客户端：GET mykey&lt;br /&gt;
服务器：foobar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 服务器实际发送的内容为：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;$6\r\nfoobar\r\n&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 如果被请求的值不存在， 那么批量回复会将特殊值 -1 用作回复的长度值，就像这样：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
客户端：GET non-existing-key&lt;br /&gt;
服务器：$-1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 这种回复称为'''空批量回复'''（NULL Bulk Reply）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
当请求对象不存在时，客户端应该返回空对象，而不是空字符串。&lt;br /&gt;
: 比如 Ruby 库应该返回 nil，而 C 库应该返回 NULL（或者在回复对象中设置一个特殊标志），诸如此类。&lt;br /&gt;
&lt;br /&gt;
=== 多条批量回复 ===&lt;br /&gt;
 像 LRANGE 这样的命令需要返回多个值，这一目标可以通过多条批量回复来完成。&lt;br /&gt;
 &lt;br /&gt;
 多条批量回复是'''由多个回复组成的数组'''，数组中的每个元素都可以是任意类型的回复，包括多条批量回复本身。&lt;br /&gt;
 &lt;br /&gt;
 多条批量回复的第一个字节为 “'''*'''”，后跟一个字符串表示的整数值，这个值记录了多条批量回复所包含的回复数量，再后面是一个 '''CRLF'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：服务器发送的所有字符串都由 CRLF 结尾&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
客户端： LRANGE mylist 0 3&lt;br /&gt;
服务器： *4&lt;br /&gt;
服务器： $3&lt;br /&gt;
服务器： foo&lt;br /&gt;
服务器： $3&lt;br /&gt;
服务器： bar&lt;br /&gt;
服务器： $5&lt;br /&gt;
服务器： Hello&lt;br /&gt;
服务器： $5&lt;br /&gt;
服务器： World&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
正如你所见到的那样，多条批量回复所使用的格式，和客户端发送命令时使用的统一请求协议的格式一模一样。它们之间的唯一区别是：&lt;br /&gt;
# 统一请求协议只发送批量回复。&lt;br /&gt;
# 而服务器应答命令时所发送的多条批量回复，则可以包含任意类型的回复。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以下例子展示了一个多条批量回复，回复中包含四个整数值，以及一个二进制安全字符串：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
*5\r\n&lt;br /&gt;
:1\r\n&lt;br /&gt;
:2\r\n&lt;br /&gt;
:3\r\n&lt;br /&gt;
:4\r\n&lt;br /&gt;
$6\r\n&lt;br /&gt;
foobar\r\n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 在回复的第一行，服务器发送“*5\r\n”，表示这个多条批量回复包含 5 条回复，再后面跟着的则是 5 条回复的正文。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 多条批量回复也可以是空白的（empty），就像这样：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
客户端： LRANGE nokey 0 1&lt;br /&gt;
服务器： *0\r\n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无内容的多条批量回复（null multi bulk reply）也是存在的，比如当 BLPOP 命令的阻塞时间超过最大时限时，它就返回一个无内容的多条批量回复，这个回复的计数值为 -1：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
客户端： BLPOP key 1&lt;br /&gt;
服务器： *-1\r\n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 客户端库应该区别对待“'''空白多条回复'''”和“'''无内容多条回复'''”：当 Redis 返回一个无内容多条回复时，客户端库应该返回一个 null 对象，而不是一个空数组。&lt;br /&gt;
&lt;br /&gt;
==== 多条批量回复中的空元素 ====&lt;br /&gt;
 多条批量回复中的元素可以将自身的长度设置为 -1，从而表示该元素不存在，并且也不是一个空白字符串（empty string）。&lt;br /&gt;
 &lt;br /&gt;
 当 SORT 命令使用 GET pattern 选项对一个不存在的键进行操作时，就会发生多条批量回复中带有空白元素的情况。&lt;br /&gt;
&lt;br /&gt;
以下例子展示了一个包含空元素的多重批量回复：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
服务器： *3&lt;br /&gt;
服务器： $3&lt;br /&gt;
服务器： foo&lt;br /&gt;
服务器： $-1&lt;br /&gt;
服务器： $3&lt;br /&gt;
服务器： bar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 其中，回复中的第二个元素为空。&lt;br /&gt;
对于这个回复，客户端库应该返回类似于这样的回复：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[&amp;quot;foo&amp;quot;, nil, &amp;quot;bar&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 多命令和流水线 ==&lt;br /&gt;
'''客户端可以通过流水线，在一次写入操作中发送多个命令'''：&lt;br /&gt;
* 在发送新命令之前，无须阅读前一个命令的回复。&lt;br /&gt;
* 多个命令的回复会在最后一并返回。&lt;br /&gt;
&lt;br /&gt;
== 内联命令 ==&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
</feed>