Redis comes with the redis-cli command-line tool. This is a simple, yet powerful tool that allows you to write, query, and otherwise manage the key/values stored in your Redis instance. To run redis-cli (as demonstrated in the previous section), you can invoke it from the command line. To avoid the extra step of authentication, I'll send the password along with the -a flag:
src/redis-cli -a currentHorseBatteryStaple -n 0
You can also specify the database number with the -n flag. If you do not specify it, redis-cli will connect to the database 0 (zero) by default. Additionally, you can change databases with the SELECT command:
127.0.0.1:6379> SELECT 0
To start with, let's set a simple message in database 0. We will name the key packt:welcome and set it to the value of Hello world!:
127.0.0.1:6379> set packt:welcome "Hello world!"
Similarly, we can query the value for the packt:welcome key like this:
127.0.0.1:6379> get packt:welcome "Hello world!"
Redis also allows you to get and set the value of a key in the same command using getset. When complete, it returns the original value held by the key, before the set was applied:
127.0.0.1:6379> getset packt:welcome "Hello world from getset!" "Hello world!" 127.0.0.1:6379> get packt:welcome "Hello world from getset!"
Now, let's assume we wanted to store a leaderboard for video game scores. We can add some scores (via the redis-cli) to a set type, and display them like this:
127.0.0.1:6379>zadd games:joust 48850 Connor (integer) 1 127.0.0.1:6379>zadd games:joust 58150 Dad (integer) 1 127.0.0.1:6379>zadd games:joust 49910 Toria (integer) 1 127.0.0.1:6379>zadd games:joust 29910 Toria (integer) 0 127.0.0.1:6379>zrange games:joust 0 -1 WITHSCORES 1) "Toria" 2) "29910" 3) "Connor" 4) "48850" 5) "Dad" 6) "58150"
Redis stores items in sorted sets by a score in ascending order. It is also possible to return the set in descending order, which makes more sense for a video game leaderboard:
127.0.0.1:6379>zrevrange games:joust 0 -1 WITHSCORES 1) "Dad" 2) "58150" 3) "Connor" 4) "48850" 5) "Toria" 6) "29910"
This shows how easy it is to manage sets, as well as how Redis handles uniqueness and sort order. Note that the zrange and zrevrange commands return items in a set starting and ending with specific indexes. For this example, we are specifying a starting index of 0 (the first position) and an ending index of -1 to return the entire list.
Now let's switch gears a little bit, and use Redis to keep track of our logins. A very useful datatype in Redis is the list type. The list type allows you to push new items into the list, from either the right side or the left side (rpush versus lpush). Similarly, you can pop existing elements off of the list, from either the right or left side (rpop versus lpop).
Let's assume that we want to use Redis to keep track of the most recently logged-in users for our application. Here, we will add a new user to the packt:logins:
127.0.0.1:6379>lpush packt:logins "aploetz 10.0.0.4 2017-06-24 16:22:04.144998" (integer) 1
If the list key does not exist at the time a new item is added to it, it is created. Additionally, the current size of the list is returned after the command completes. Here we will add another item to the list, and then query it using the lrange command:
127.0.0.1:6379>lpush packt:logins "aploetz 10.0.0.4 2017-06-24 16:31:58.171875" (integer) 2 127.0.0.1:6379>lrange packt:logins 0 -1 1) "aploetz 10.0.0.4 2017-06-24 16:31:58.171875" 2) "aploetz 10.0.0.4 2017-06-24 16:22:04.144998"
Note that lrange allows you to query a specified range of items from a list, starting at the left side. It takes integers for the start and stop indexes of the list. Like we saw with zrange and zrevrange, passing it a start of 0 (zero) and stop off -1 returns all contents of the list as output.
Next, let's look at utilizing Redis' Publish/Subscribe feature. The way this works is that one command is used to create messages and push them to a channel. At the same time, additional commands can be used to listen to the channel and display the messages as they come in.
To properly demonstrate this, we will need two terminal windows. On one terminal window, we will set up our subscriber:
src/redis-cli -a currentHorseBatteryStaple -n 0 127.0.0.1:6379> subscribe greeting Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "greeting" 3) (integer) 1
In this case, we have used the subscribe command to listen for messages posted to the greeting channel. After executing the command, we are presented with text informing us that we are currently Reading messages... and that we can quit this phase by pressing Ctrl + C.
Additionally, we see three (numbered) lines of text. This is because each message is an[7] array reply with three elements. The first element tells us that we have succeeded in subscribing to a channel. The second is informing us that we are listening to the greeting channel. The third element is providing us with the total number of channels that we are currently subscribing to; in our case, that is only one (1).
Now, let's switch over to our other terminal window, and also run redis-cli to our local instance:
src/redis-cli -a currentHorseBatteryStaple -n 0
Once we're in, let's go ahead and publish two messages to the greeting channel:
127.0.0.1:6379> publish greeting "Hello world!" (integer) 1 127.0.0.1:6379> publish greeting "Hello world from pub/sub" (integer) 1
The output from each publish command informs us that our message was received by one (1) subscriber.
Now, if we look at our first terminal window (which we have set up as our subscriber), here is what is displayed:
1) "message" 2) "greeting" 3) "Hello world!" 1) "message" 2) "greeting" 3) "Hello world from pub/sub!"
To get out of subscribe mode we can simply hit Ctrl + C. Unfortunately, that also exits us out of the redis-cli. Additionally, we can also use the unsubscribe command. The unsubscribe command can be used to unsubscribe a client from a specific channel. Without specifying a channel, the client is unsubscribed from all channels:
127.0.0.1:6379> unsubscribe 1) "unsubscribe" 2) (nil) 3) (integer) 0
In this case, our output is telling us that we have successfully unsubscribed and that we are currently subscribed to zero (0) channels.