What happens if two simultaneous set to redis? - redis

For example, assuming the network is slow
00:00:00
client 1: set key1 a-very-big-value-around-400MB
client 2: set key1 short-value (Does this get blocked as client 1 is setting key1?)
If not block:
00:00:01
client 1: still writing to key1
client 2: successfully returned
00:00:02
client 1: still writing to key1
client 2: get key1 (return short-value?)
00:01:00
client 1: finished writing
client 2: get key1 (return short-value or a-very-big-value-around-400MB or something corrupted
?)
If a-very-big-value-around-400MB is returned, does this mean that redis first writes the value to some temp key then rename the key to key1??

Related

Redis streams is returning an empty array

I created a new Redis steam using the following command.
XGROUP CREATE A mygroup $ MKSTREAM
I added the below mentioned data
xadd A * X 1
xadd A * X 2
xadd A * X 3
xadd A * X 4
I am reading the data using the following command.
XREADGROUP GROUP mygroup Alice COUNT 1 STREAMS A 0
Its returning an empty array
1) 1) "A"
2) (empty array)
I am using Redis version 6.2.1. Kindly help me to debug the error.
When you use XREADGROUP command to read message, you should specify > as ID, instead of 0.
Reference from the doc:
The special > ID, which means that the consumer want to receive only messages that were never delivered to any other consumer. It just means, give me new messages.
Any other ID, that is, 0 or any other valid ID or incomplete ID (just the millisecond time part), will have the effect of returning entries that are pending for the consumer sending the command with IDs greater than the one provided. So basically if the ID is not >, then the command will just let the client access its pending entries: messages delivered to it, but not yet acknowledged. Note that in this case, both BLOCK and NOACK are ignored.
If ID is not >, you can only read pending messages, however, in your case, there's no pending message, since you have not consume anything.

Is MULTI supposed to work on Redis clustered?

I'm using Redis on a clustered db (locally). I'm trying the MULTI command, but it seems that it is not working. Individual commands work and I can see how the shard moves.
Is there anything else I should be doing to make MULTI work? The documentation is unclear about whether or not it should work. https://redis.io/topics/cluster-spec
In the example below I just set individual keys (note how the port=cluster changes), then trying a multi command. The command executes before EXEC is called
127.0.0.1:30001> set a 1
-> Redirected to slot [15495] located at 127.0.0.1:30003
OK
127.0.0.1:30003> set b 2
-> Redirected to slot [3300] located at 127.0.0.1:30001
OK
127.0.0.1:30001> MULTI
OK
127.0.0.1:30001> HSET c f val
-> Redirected to slot [7365] located at 127.0.0.1:30002
(integer) 1
127.0.0.1:30002> HSET c f2 val2
(integer) 1
127.0.0.1:30002> EXEC
(error) ERR EXEC without MULTI
127.0.0.1:30002> HGET c f
"val"
127.0.0.1:30002>
MULTI transactions, as well as any multi-key operations, are supported only within a single hashslot in a clustered Redis deployment.

What is the race condition for Redis INCR Rate Limiter 2?

I have read the INCR documentation here but I could not understand why the Rate limiter 2 has a race condition.
In addition, what does it mean by the key will be leaked until we'll see the same IP address again in the documentation?
Can anyone help explain? Thank you very much!
You are talking about the following code, which has two problems in multiple-threaded environment.
1. FUNCTION LIMIT_API_CALL(ip):
2. current = GET(ip)
3. IF current != NULL AND current > 10 THEN
4. ERROR "too many requests per second"
5. ELSE
6. value = INCR(ip)
7. IF value == 1 THEN
8. EXPIRE(ip,1)
9. END
10. PERFORM_API_CALL()
11.END
the key will be leaked until we'll see the same IP address again
If the client dies, e.g. client is killed or machine is down, before executing LINE 8. Then the key ip won't be set an expiration. If we'll never see this ip again, this key will always persist in Redis database, and is leaked.
Rate limiter 2 has a race condition
Suppose key ip doesn't exist in the database. If there are more than 10 clients, say, 20 clients, execute LINE 2 simultaneously. All of them will get a NULL current, and they all will go into the ELSE clause. Finally all these clients will execute LINE 10, and the API will be called more than 10 times.
This solution fails, because these's a time window between LINE 2 and LINE 3.
A Correct Solution
value = INCR(ip)
IF value == 1 THEN
EXPIRE(ip, 1)
END
IF value <= 10 THEN
return true
ELSE
return false
END
Wrap the above code into a Lua script to ensure it runs atomically. If this script returns true, perform the API call. Otherwise, do nothing.

How do I selectively share data with clients, so that they only see their own data, and not of their competitors?

I have data like this in my Excel 2013 workbook
Table 1:
Col A Col B Col B
1 Client 1 ..... 123
2 Client 1 ..... 456
3 Client 1 ..... 99
4 Client 2 ..... 324
5 Client 2 ..... 989
6 Client 3 ..... 234
7 Client 3 ..... 23
I am using this Table 1 for a client specific report elsewhere in the excel. e.g.
Client Report: Client 1
Col A Col B Col C Col D
1 Client 1 123 456 99
The cell A1 in the report is a data validation dropdown containing the names of the Clients. I can change that dropdown to Client 2
Client Report: Client 2
Col A Col B Col C Col D
1 Client 2 324 989
What I want to be able to do is send out one file to all clients, which contains the Client Report, but each Client should only be able to see their own data. As a bonus, each client should also not be able to see which other clients are on the list (i.e. in the file that Client 1 receives, he/she should not have access to the numbers of Client 2 and Client 3, and as a bonus, should not even see the names Client 2 and Client 3)
I have an option of creating these files manually, for each client. I am looking for a way to hide data in a file depending on which Client it is for, and thus sending out the same file to multiple clients (I have ~30 clients, so the manual process will be error prone and a pain). I don't want to create 30 separate files or sheets if I can help it. The ideal way would be to build a 'master' option, which gives me access to all data, but not to the client who I send this out to. However, data confidentiality is super critical, and if password protection in Excel Workbooks is questionable, then I would not want this option, and I will go back to manual :)
Also, even though I am only looking for vanilla Excel solutions (I can't rely on my clients to have addons installed or install one just for the sake of this), if you do know of interesting ways to address this kind of a problem with addons, please do comment/answer.
Thanks!
As Steven Martain said, there is NO SECURITY in Excel. You can password-protect your Workbook, but the password can be broken in no time at all. Instead split your file into several separate files. Please see this link for an idea of how to do this.
http://www.rondebruin.nl/win/s3/win006.htm
Then, simply email the different files to different recipients/clients/people. See this link for an idea of how to do that.
http://www.rondebruin.nl/win/s1/outlook/amail6.htm
It is not possible to do it without coding/VB. However, you can use InstaRow ( check here). Which is perfect tool for this problem. You can signup with email id ( and your clients). They will see exactly their portion.
They can even change data easily.
Posting #StevenMartin 's answer from the comments above, as it seems to the way to go about it
"Write a macro to spit out 30 workbooks - a simple search would tell you excel password protection can be broken in seconds"

my redis keys do not expire

My redis server does not delete keys when the time-to-live reaches 0.
Here is a sample code:
redis-cli
>SET mykey "ismykey"
>EXPIRE mykey 20
#check TTL
>TTL mykey
>(integer) 17
> ...
>TTL mykey
>(integer) -1
#mykey chould have expired:
>EXISTS mykey
>(integer) 1
>#oh still there, check its value
>GET mykey
>"ismykey"
If i check the info return by redis, it says 0 keys were expired.
Any idea?
thanks.
Since you're doing a '...' it's hard to say for sure, but I'd say you're setting mykey during that part, which will effectively remove the expiration.
From the EXPIRE manual
The timeout is cleared only when the key is removed using the DEL
command or overwritten using the SET or GETSET commands
Also, regarding the -1 reply from TTL
Return value
Integer reply: TTL in seconds or -1 when key does not
exist or does not have a timeout.
EDIT: Note that this behaviour changed in Redis 2.8
Starting with Redis 2.8 the return value in case of error changed:
The command returns -2 if the key does not exist.
The command returns -1 if the key exists but has no associated expire.
In other words, if your key exists, it would seem to be persistent, ie not have any expiration set.
EDIT: It seems I can reproduce this if I create the key on a REDIS slave server, the slave will not delete the key without master input, since normally you would not create keys locally on a slave. Is this the case here?
However while the slaves connected to a master will not expire keys
independently (but will wait for the DEL coming from the master),
they'll still take the full state of the expires existing in the
dataset, so when a slave is elected to a master it will be able to
expire the keys independently, fully acting as a master.