Update scripting doc

This commit is contained in:
Jennifer Hickey
2013-08-05 16:07:14 -07:00
parent 113c215554
commit 4630de10d1

View File

@@ -2,24 +2,68 @@
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="scripting">
<title>Redis Scripting</title>
<para>Redis versions 2.6 and higher provide support for execution of Lua scripts through the <ulink url="http://redis.io/commands/eval">eval</ulink> and
<ulink url="http://redis.io/commands/evalsha">evalsha</ulink> commands. These operations as well as other script management operations are available on the
<interfacename>RedisConnection</interfacename> implementations.
<ulink url="http://redis.io/commands/evalsha">evalsha</ulink> commands. Spring Data Redis provides a high-level abstraction for script execution
that handles serialization and automatically makes use of the Redis script cache.
</para>
<para>Future SDR versions may offer support for these scripting commands on a higher-level API, such as <literal>RedisTemplate</literal>.</para>
<para>Scripts can be run through the <literal>execute</literal> methods of <classname>RedisTemplate</classname>. RedisTemplate uses a configurable
<interfacename>ScriptExecutor</interfacename> to execute the provided script. By default, the <interfacename>ScriptExecutor</interfacename> takes care of
serializing the provided keys and arguments and deserializing the script result. This is done with the <classname>RedisTemplate</classname> key and value serializers.
There is an additional <literal>execute</literal> method that allows you to pass custom serializers for the script arguments and result.</para>
<para>Here's an example script execution:</para>
<para>The default <interfacename>ScriptExecutor</interfacename> optimizes performance by retrieving the SHA1 of the script and attempting first to
run <literal>evalsha</literal>, falling back to <literal>eval</literal> if the script is not yet present in the Redis script cache.</para>
<programlisting language="java"><![CDATA[// execute script
Long magicNumber = redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.eval("return 10", ReturnType.INTEGER, 0);
<para>Here's an example that executes a common "check-and-set" scenario using a Lua script. This is an ideal use case for a Redis script, as
it requires that we execute a set of commands atomically and the behavior of one command is influenced by the result of another.</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="script" class="org.springframework.data.redis.core.script.DefaultRedisScript">
<property name="location" value="classpath:META-INF/scripts/checkandset.lua"/>
<property name="resultType" value="java.lang.Boolean"/>
</bean>
...
</beans>]]></programlisting>
<programlisting language="java"><![CDATA[
public class Example {
@Autowired
RedisScript<Boolean> script;
public boolean checkAndSet(String expectedValue, String newValue) {
return redisTemplate.execute(script, Collections.singletonList("key"),
expectedValue, newValue);
}
});]]></programlisting>
}]]></programlisting>
<para>The return values of <literal>eval</literal> and <literal>evalsha</literal> can be assigned to any type. However, they should
match the expected <literal>ReturnType</literal> passed to these methods. In the above example, we passed ReturnType.Integer, therefore
the return type of <literal>eval</literal> was a Long. Similarly, using ReturnType.VALUE will yield a byte[]. See the ReturnType javadoc
for details.</para>
<programlisting language="lua">
-- checkandset.lua
local current = redis.call('GET', KEYS[1])
if current == ARGV[1]
then
redis.call('SET', KEYS[1], ARGV[2])
return true
end
return false
</programlisting>
<para>The XML above configures a <classname>DefaultRedisScript</classname> pointing to a file called <literal>checkandset.lua</literal>, which is
expected to return a boolean value. The script <literal>resultType</literal> should be one of Long, Boolean, List, or deserialized value type. It can also be null if the
script returns a throw-away status (i.e "OK"). It is ideal to configure a single instance of <classname>DefaultRedisScript</classname> in your application context to avoid
re-calcuation of the script's SHA1 on every script execution.
</para>
<para>The checkAndSet method above then executes the configured <interfacename>RedisScript</interfacename> with the provided key and arguments and returns the result.</para>
<para>Scripts can be executed within a <interfacename>SessionCallback</interfacename> as part of a transaction or pipeline.
See <xref linkend="tx"/> and <xref linkend="pipeline"/> for more information.</para>
<para>The scripting support provided by Spring Data Redis also allows you to schedule Redis scripts for periodic execution using the Spring Task
and Scheduler abstractions. See the <literal>Spring Framework</literal> documentation for more details.</para>
</section>