(tested with Redis version 3.0.0 (2.9.104 to be precise))
Make sure a Redis server is running.
<code>(ql:quickload 'cl-redis)</code>
Connect to the server to the given host and port with <code>(redis:connect :host <host> :port <port>)</code> (<code>host</code> defaults to <code>127.0.0.1</code>, <code>port</code> — to <code>6379</code>).
Interact with the server using Redis commands from the <code>red</code> package.
Disconnect from the server with <code>(redis:disconnect)</code>.
Alternatively, wrap the whole interaction session in <code>with-connection</code> macro, which accepts the same arguments as <code>connect</code> does, opens a socket connection, executes the body of the macro with the current connection (<code>*connection*</code>) bound to this new connection, and ensures that the connection is closed afterwards.
The system provides 2 packages: <code>REDIS</code> and <code>RED</code>. All the functionality is available from the <code>REDIS</code> package. Not to cause symbol clashes, Redis commands are defined in this package with a prefix (which defaults to <code>red-</code> and is set at compilation time). The package <code>RED</code> is a syntactic sugar — it just provides the Redis commands without a prefix. So it is not intended to be imported to avoid symbol conflicts with package <code>COMMON-LISP</code> — just use the package-qualified symbol names: i.e. the same Redis command (for instance <code>GET</code>) can be called as <code>RED-GET</code> (if you import the <code>REDIS</code> package) or <code>RED:GET</code>.
Available through quicklisp.
usocket
flexi-streams
rutils
only for tests: nuts, bordeaux-threads
If <code>*echo-p*</code> is <code>T</code>, all client-server communications will be echoed to the stream <code>*echo-stream*</code>, which defaults to <code>*standard-output*</code>.
Error handling is mimicked after Postmodern. In particular, whenever an error occurs that breaks the communication stream, a condition of type <code>redis-connection-error</code> is signalled offering a <code>:reconnect</code> restart. If it is selected the whole Redis command will be resent, if the reconnection attempt succeeds. Furthermore, <code>connect</code> checks if a connection to Redis is already established, and offers two restarts (<code>:leave</code> and <code>:replace</code>) if this is the case.
When the server respondes with an error reply (i.e., a reply that starts with <code>-</code>), a condition of type <code>redis-error-reply</code> is signalled.
There's also a high-level <code>with-persistent-connection</code> macro, that tries to do the right thing™ (i.e. automatically reopen the connection once, if it is broken).
Since there's no special command to receive messages from Redis via PubSub here's how you do it:
To publish, obviously:
For better performance Redis allows to pipeline commands and delay receiving results until the end, and process them all in oine batch afterwards. To support that there's <code>with-pipelining</code> macro. Compare execution times in the following examples (with pipelining and without: 6.567 secs vs. 2023.924 secs!):
Note, that <code>with-pipelining</code> calls theoretically may nest, but the results will only be available to the highest-level pipeline, all the nested pipelines will return :PIPELINED. So a warining is signalled in this situation.
Generic functions <code>tell</code> and <code>expect</code> implement the Redis protocol according to the spec. <code>tell</code> specifies how a request to Redis is formatted, <code>expect</code> — how the response is handled. The best way to implement another method on <code>expect</code> is usually with <code>def-expect-method</code>, which arranges reading data from the socket and provides a variable <code>reply</code>, which holds the decoded reply data from the server with the initial character removed. For example:
Redis operations are defined as ordinary functions by <code>def-cmd</code> for which only arguments and return type should be provided.<code>def-cmd</code> prefixes all the defined functions' names with <code>*cmd-prefix*</code>, which defaults to <code>'red</code>. (Note, that setting of <code>*cmd-prefix*</code> will have its effects at compile time). It also exports them from <code>REDIS</code> package, and from <code>RED</code> package without the prefix.
An example of command definition is given below:
See <code>commands.lisp</code> for all defined commands.
The following commands are not implemented, because they are not intended for use in client: <code>MONITOR</code>, <code>DEBUG OBJECT</code>, and <code>DEBUG SEGFAULT</code>.
Support for Unix domain sockets — planned
Consistent hashing isn't built-in. Actually, such thing is orthogonal to the functionality of this library and, probably, should be implemented in a separate library.
Connection pooling is also not implemented, because in the presence of <code>with-persistent-connection</code> it is actually not needed so much. Persistent connections are more simple, efficient and less error-prone for dedicated threads. But there are other use-cases for pooling, so it will probably be implemented in future releases.
The library is developed and maintained by Vsevolod Dyomkin [email protected].
At the initial stages Alexandr Manzyuk [email protected] developed the connection handling code following the implementation in Postmodern. It was since partially rewritten to accommodate more advanced connection handling strategies, like persistent connection.
MIT (See LICENSE file for details).
本文作者:陳群
本文來自雲栖社群合作夥伴rediscn,了解相關資訊可以關注redis.cn網站。