Redis - ttulka/technologies GitHub Wiki
Redis is in the family of databases called key-value stores.
Create, read, test, and delete the value:
SET server:name "tux1"
GET server:name
EXISTS server:name
DEL server:name
Increment and decrement the value:
INCR counter
INCRBY counter 100
DECR counter
DECRBY counter 100
All the Redis operations implemented by single commands are atomic.
A key can be set to expire with EXPIRE
command, TTL
command tests how long a key will exist:
SET resource:lock "Demo"
EXPIRE resource:lock 120
TTL resource:lock
The -2
for the TTL
of the key means that the key does not exist (anymore). A -1
for the TTL
of the key means that it will never expire.
Expiration will be reset when SET
again. Atomically:
SET resource:lock "Demo" EX 120
It is also possible to cancel the time to live of a key removing the expire and making the key permanent again:
PERSIST resource:lock
TTL resource:lock
Redis also supports several more complex data structures.
A list is a series of ordered values.
RPUSH
puts the new element at the end of the list:
RPUSH friends "Alice"
RPUSH friends "Bob"
LPUSH
puts the new element at the start of the list:
LPUSH friends "Joe"
LRANGE
gives a subset of the list. A value of -1
for the second parameter means to retrieve elements until the end of the list, -2
means to include up to the penultimate, and so forth:
LRANGE friends 0 -1 => 1) "Joe", 2) "Alice", 3) "Bob"
LRANGE friends 0 1 => 1) "Joe", 2) "Alice"
LRANGE friends 1 2 => 1) "Alice", 2) "Bob"
LPOP
removes the first element from the list and returns it:
LPOP friends => "Sam"
RPOP
removes the last element from the list and returns it:
RPOP friends => "Bob"
The list now only has one element:
LLEN friends => 1
LRANGE friends 0 -1 => 1) "Alice"
Both RPUSH
and LPUSH
commands are variadic, so you can specify multiple elements in the same command execution:
RPUSH friends 1 2 3 => 4
A set does not have a specific order and each element may only appear once.
SADD
adds the given member to the set, again this command is also variadic:
SADD superpowers "flight" "reflexes"
The return value of SADD
returns 0
if the element we try to add is already inside, otherwise 1
is returned:
SADD superpowers "flight" => 0
SADD superpowers "invisibility" => 1
SREM
removes the given member from the set, returning 1
or 0
to signal if the member was actually there or not:
SREM superpowers "flight" => 1
SREM superpowers "making pizza" => 0
SISMEMBER
tests if the given value is in the set. It returns 1
if the value is there and 0
if it is not:
SISMEMBER superpowers "flight" => 1
SISMEMBER superpowers "invisibility" => 0
SMEMBERS
returns a list of all the members of this set:
SMEMBERS superpowers => 1) "flight", 2) "invisibility"
SUNION
combines two or more sets and returns the list of all elements:
SADD birdpowers "pecking"
SADD birdpowers "flight"
SUNION superpowers birdpowers => 1) "pecking", 2) "invisibility", 3) "flight"
A sorted set is similar to a regular set, but now each value has an associated score.
ZADD hackers 1940 "Alan Kay"
ZADD hackers 1969 "Linus Torvalds"
ZADD hackers 1912 "Alan Turing"
Hashes are maps between string fields and string values, so they are the perfect data type to represent objects:
HSET user:1000 name "John Smith"
HSET user:1000 email "[email protected]"
HSET user:1000 password "s3cret"
You can also set multiple fields at once:
HMSET user:1001 name "Mary Jones" password "hidden" email "[email protected]"
Use HGETALL
to get back the saved data:
HGETALL user:1000
HGET user:1001 name => "Mary Jones"
Numerical values in hash fields are handled exactly the same as in simple strings and there are operations to increment this value in an atomic way:
HSET user:1000 visits 10
HINCRBY user:1000 visits 1 => 11
HINCRBY user:1000 visits 10 => 21
HDEL user:1000 visits
HINCRBY user:1000 visits 1 => 1
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>...</version>
</dependency>
JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");
/// Jedis implements Closeable. Hence, the jedis instance will be auto-closed after the last statement.
try (Jedis jedis = pool.getResource()) {
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
}
/// ... when closing your application:
pool.close();
jedis.set("events/city/rome", "32,15,223,828");
String cachedResponse = jedis.get("events/city/rome");
jedis.lpush("queue#tasks", "firstTask");
jedis.lpush("queue#tasks", "secondTask");
String task = jedis.rpop("queue#tasks");
jedis.sadd("nicknames", "nickname#1");
jedis.sadd("nicknames", "nickname#2");
jedis.sadd("nicknames", "nickname#1");
Set<String> nicknames = jedis.smembers("nicknames");
boolean exists = jedis.sismember("nicknames", "nickname#1");
jedis.hset("user#1", "name", "Peter");
jedis.hset("user#1", "job", "politician");
String name = jedis.hget("user#1", "name");
Map<String, String> fields = jedis.hgetAll("user#1");
String job = fields.get("job");
Map<String, Double> scores = new HashMap<>();
scores.put("PlayerOne", 3000.0);
scores.put("PlayerTwo", 1500.0);
scores.put("PlayerThree", 8200.0);
scores.entrySet().forEach(playerScore -> {
jedis.zadd(key, playerScore.getValue(), playerScore.getKey());
});
String player = jedis.zrevrange("ranking", 0, 1).iterator().next();
long rank = jedis.zrevrank("ranking", "PlayerOne");
String friendsPrefix = "friends#";
String userOneId = "4352523";
String userTwoId = "5552321";
Transaction t = jedis.multi();
t.sadd(friendsPrefix + userOneId, userTwoId);
t.sadd(friendsPrefix + userTwoId, userOneId);
t.exec();
String userOneId = "4352523";
String userTwoId = "4849888";
Pipeline p = jedis.pipelined();
p.sadd("searched#" + userOneId, "paris");
p.zadd("ranking", 126, userOneId);
p.zadd("ranking", 325, userTwoId);
Response<Boolean> pipeExists = p.sismember("searched#" + userOneId, "paris");
Response<Set<String>> pipeRanking = p.zrange("ranking", 0, -1);
p.sync();
String exists = pipeExists.get();
Set<String> ranking = pipeRanking.get();
Jedis jSubscriber = new Jedis();
jSubscriber.subscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
// handle message
}
}, "channel");
Jedis jPublisher = new Jedis();
jPublisher.publish("channel", "test message");