Unable to get keys on redis cluster - redis

I have created a cache key on redis cluster with cacheKey as "citylist_[object Object]"
When i am trying to get the keys on cluster mode with pattern keys citylist* on redis. It is returning me (empty array)
but when i am trying to get the value directly using get "citylist_[object Object]" , it returns me the value.
how to search the keys using the pattern for above mentioned cache key.

Very simple test on my local Redis (v6.2.4):
127.0.0.1:6379> set "citylist_[object Object]" test_value
OK
127.0.0.1:6379> keys citylist*
1) "citylist_[object Object]"

Related

how to redis hset only if key exists

I use redis to cache my web blog.My article has a field "checked",if this field changed in database,I also need to set the new value to redis,here is code
if redis_conn.exists("article"):
redis_conn.hset("article", "checked",1)
it seems like ok,but if article key expired after exists and before hset,there will be some problems.the article key will only has one field of checked,other field like title,content,etc...will gone.
how to hset only if key exists,if key is expired just do nothing.
You can use a Lua script for that, i.e. (pseudo NodeJS):
redis_conn.eval("if redis.call('EXISTS', KEYS[1])==1 then redis.call('HSET', KEYS[1], ARGV[1], ARGV[2]) end", 1, "article", "checked", 1)
Server-side Lua scripts are atomic, so you are assured that the key will not expire in between calls.
Note: Redis does have the HSETNX command, but not the HSETEX command, which is apparently what you're looking for.

Using RPUSH with TTL in a single command in Redis

I'm trying to push an entry in a list in Redis and also want to update the TTL of the list every time a new entry comes in. I can do that my simple calling the EXPIRE "my-list" ttl using Redis. Since my application is receiving heavy traffic, I want to reduce the number of calls to redis.
Can I set my TTL during the push operation in Redis, i.e RPUSH "mylist" I1 I2...IN ex "TTL", does redis support this time of command functionality. I can see that it does support this for the String data structures.
Redis does not have dedicated commands to push and expire the List, although as you've mentioned it does have something like that for the String data type.
The way you'd go about this challenge is to compose your own "command" from existing ones. Instead of having your application call these commands, however, you would use a Lua script as explained in the EVAL documentation page.
Lua scripts are cached and run atomically on the server. One such as the following would probably help in your case - it expects to get the key name, the pushed element and the expiry value:
local reply = redis.call('RPUSH', KEYS[1], ARGV[1])
redis.call('EXPIRE', KEYS[1], ARGV[2])
return reply

Share redis storage between multiple apps

I am using redis in a node application for caching data and now i want to access and modify stored data using a django application on the same server but i can't access to the data.
Django connection:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
using keys * command in terminal:
$ redis-cli
127.0.0.1:6379> keys *
1) "sess:Ok0eYOko5WaV7njfX04qgqG1oYe0xiL1" -> this key is set in node
2) ":1:from-django" -> this key is set in django
Accessing keys in django application:
keys = cache.keys('*')
print(keys) # prints only one key => ['from-django']
I can't access first key that is set in node application and also django stored keys are prifixed with :1: by default!
I want to share all keys between node and django but they only access their own keys.
Any idea?
You can access all of data from any where, But you are working with Redis in Cache model! and all of Cache systems has own unique data structure, You must work with Redis in Database model and scan it yourself.
Use Python Redis package to access all of Redis in your application.

Ignite and Kafka Integration

I am trying the Ignite and Kafka Integration to bring kafka message into Ignite cache.
My message key is a random string(To work with Ignite, the kafka message key can't be null), and the value is a json string representation for Person(a java class)
When Ignite receives such a message, it looks that Ignite will use the message's key(the random string in my case) as the cache key.
Is it possible to change the message key to the person's id, so that I can put the into the cache.
Looks that streamer.receiver(new StreamReceiver) is workable
streamer.receiver(new StreamReceiver<String, String>() {
public void receive(IgniteCache<String, String> cache, Collection<Map.Entry<String, String>> entries) throws IgniteException {
for (Map.Entry<String, String> entry : entries) {
Person p = fromJson(entry.getValue());
//ignore the message key,and use person id as the cache key
cache.put(p.getId(), p);
}
}
});
Is this the recommended way? and I am not sure whether calling cache.put in StreamReceiver is a correct way, since it is only a pre-processing step before writing to cache.
Data streamer will map all your keys to cache affinity nodes, create batches of entries and send batches to affinity nodes. After it StreamReceiver will receive your entries, get Person's ID and invoke cache.put(K, V). Putting entry lead to mapping your key to corresponding cache affinity node and sending update request to this node.
Everything looks good. But result of mapping your random key from Kafka and result of mapping Person's ID will be different (most likely different nodes). As result your will get poor performance due to redundant network hops.
Unfortunately, current KafkaStreamer implementations doesn't support stream tuple extractors (see e.g. StreamSingleTupleExtractor class). But you can easily create your own Kafka streamer implementation using existing one as example.
Also you can try use KafkaStreamer's keyDecoder and valDecoder in order to extract Person's ID from Kafka message. I don't sure, but it can help.

Redis Booksleeve - How to use Hash API properly

i am using the Booksleeve hash api for Redis. I am doing the following:
CurrentConnection.Hashes.Set(0, "item:1", "priority", task.priority.ToString());
var taskResult = CurrentConnection.Hashes.GetString(0, "item:1", "priority");
taskResult.Wait();
var priority = Int32.Parse(taskResult.Result)
However i am getting an Aggregate exception:
"ERR Operation against a key holding the wrong kind of value"
I am not sure what i am doing wrong here (except of blocking the task :)).
Note: CurrentConnection is an instance of BookSleeve.RedisConnection
Please help!
Thanks
That is not a Booksleeve issue - it is a redis error; in fact, the full error message you should be seeing is:
Redis server: ERR Operation against a key holding the wrong kind of value
(where I try to make it clear that this error has come from redis, not Booksleeve)
As for what causes this: each key in redis has a designated type; string, hash, list, etc. You cannot use hash operations on something that is not a hash.
My guess, then, is that "item:1" already exists, but as something other than a hash. I have unit tests that confirm this from Booksleeve (i.e. with/without a pre-existing non-hash value).
You can investigate this in redis using redis-cli or any other client (telnet works, at a push), with the command:
type item:1
(thanks #Sripathi)