Redis Interview Questions and Answers

Redis is an open source (BSD licensed), in-memory data structure store used as a database, cache, message broker, and streaming engine.

Redis provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams.

Redis has built-in replication, Lua scripting, LRU eviction, transactions, and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

To achieve top performance, Redis works with an in-memory dataset. Depending on your use case, Redis can persist your data either by periodically dumping the dataset to disk or by appending each command to a disk-based log. You can also disable persistence if you just need a feature-rich, networked, in-memory cache.
 
Redis supports asynchronous replication, with fast non-blocking synchronization and auto-reconnection with partial resynchronization on net split.
A list of well known companies using Redis :
 
* Twitter
* GitHub
* Snapchat
* Craigslist
* StackOverflow

And many others! techstacks.io maintains a list of popular sites using Redis.
Redis is written in C, ANSI C and works on most POSIX systems like Linux, *BSD, and Mac OS X, without external dependencies.

Linux and OS X are the two operating systems where Redis is developed and tested the most, and we recommend using Linux for deployment.

Redis may work in Solaris-derived systems like SmartOS, but support is best effort. There is no official support for Windows builds.
The value for the key will be set by the SET command. And the value will get overridden by doing it over and again. 
 
On the other hand, the append contains the effect of the set only when there is no value of the key earlier. If the key already has a value assigned, then appending the key results in a value appended to the key's existing value. 
The data modeling contains the pattern and name of the data structures that should be used for storing data to achieve a dominant requirement. This is like most other databases. For instance, the primary key is used in the relational database world for establishing a relationship between two objects.

In relational databases, the data is stored in a table format, while Redis contains the data structure used for representing the domain data. We need a different design mindset for converting a relational dataset to a Redis dataset.
Redis is a NoSQL, Opensource, in-memory data-structure store. It follows the principle of key-value store.
 
It is extremely fast, persistent, portable and supports many languages such as C, C++, C#, Clojure, Common Lisp, D, Dart, Erlang, Go, Haskell, Haxe, Io, Java, JavaScript (Node.js), Julia, Lua, Objective-C, Perl, PHP, Pure Data, Python, R, Racket, Ruby, Rust, Scala, Smalltalk and Tcl.
After the installation of the server you can run the Redis Client provided by redis installation or you can open the command prompt and use the following command :
redis-cli  
By using any of them, you can interect with Redis.
Securing Redis : By default Redis binds to all the interfaces and has no authentication at all. If you use Redis in a very controlled environment, separated from the external internet and in general from attackers, that's fine. However if an unhardened Redis is exposed to the internet, it is a big security concern. If you are not 100% sure your environment is secured properly, please check the following steps in order to make Redis more secure, which are enlisted in order of increased security.
 
* Make sure the port Redis uses to listen for connections (by default 6379 and additionally 16379 if you run Redis in cluster mode, plus 26379 for Sentinel) is firewalled, so that it is not possible to contact Redis from the outside world.

* Use a configuration file where the bind directive is set in order to guarantee that Redis listens on only the network interfaces you are using. For example only the loopback interface (127.0.0.1) if you are accessing Redis just locally from the same computer, and so forth.

* Use the requirepass option in order to add an additional layer of security so that clients will require to authenticate using the AUTH command.

* Use spiped or another SSL tunneling software in order to encrypt traffic between Redis servers and Redis clients if your environment requires encryption.

Note that a Redis instance exposed to the internet without any security is very simple to exploit, so make sure you understand the above and apply at least a firewall layer. After the firewall is in place, try to connect with redis-cli from an external host in order to prove yourself the instance is actually not reachable.
* Redis is portable.

* Redis is very simple to install setup and manage.

* Redis supports simple master to slave replication.

* Redis is very fast. It can execute 100000 queries per second.

* Redis is fast because data is being persistent in memory as well as stored on the disk.

* Redis is very fast because it loads the whole dataset in primary memory.

* Redis operations working on different data types are atomic so these operations can be accomplished safely i.e. to set or increase a key, add or remove elements from a set or increase a counter.

* It supports various types of data structure such as strings, hashes, sets, lists, sorted sets etc.

* Redis supports a variety of languages i.e. C, C++, C#, Ruby, Python, Twisted Python, PHP, Erlang, Tcl, Perl, Lua, Java, Scala etc.

* If your favorite language is not supported yet, you can write your own client library, as the Protocol is pretty simple.
* Redis is very fast.

* It supports a server-side locking.

* It has a rich client side library.

* It is a good counter.

* It supports Atomic Operation.
Memcached Redis
Memcached only does caching information. It provides some more functionalities like replication and persistence along with caching information.
Memcached supports the functionality of LRU (Least Recently Used) eviction of values. LRU is not supported by Redis.
In Memcached, when they overflow memory, the one you have not used recently (LRU- Least Recently Used) will get deleted. In Redis, there is a time set for each function, Three keys are maintained, the one, which is closest to expiry, will get deleted.
CAS (Check and Set) is supported by Memcached. CAS is not supported by Redis.
Array objects are needed to be serialized in order to get saved. We need to unserialize them for their retrieval. Redis has got stronger data structures; it can handle strings, binary safe strings, list of binary safe strings, sorted lists, etc.
Memcached has at most 250 bytes length. Redis has at most 2 GB key length.
It is Multi-threaded It is single threaded.
Following are the disadvantages/ limitations of Redis :
 
* It is single threaded.

* It has got limited client support for consistent hashing.

* It has significant overhead for persistence.

* It is not deployed widely.
* Redis is a NoSQL database while RDBMS is an SQL database.

* Redis follows the key-value structure while RDBMS follows the table structure.

* Redis extremely fast while RDBMS is comparatively slow.

* Redis stores all the dataset in primary memory while RDBMS stores its dataset in secondary memory.

* Redis is generally used to store small and frequently used files while RDBMS is used to store big files.

* Redis provides only official support for Linux, BSD, Mac OS X, Solaris. It doesn?t provide official support for Windows currently while RDBMS provides support for both.
Operation keys of Redis include :

* TYPE key
* TTL key
* KEYS pattern
* EXPIRE key seconds
* EXPIREAT key timestamp
* EXISTS key
* DEL key
To improve the durability of Redis “append only file” can be configured by using fsync data on disk.

* Fsync () every time a new command is added to the append log file: It is safe but very slow

* Fysnc() one time every second : It is fast, but you may lose 1 second of data if system fails

* Never fsync() : It is an unsafe method, and your data is in hand of Operating System
While using Redis one must take care of

* Select a consistent method to name and prefix your keys. Manage your namespace

* Create a “Registry” of key prefixes that maps each of your internal documents for that application which “own” them

* For every class you put through into your Redis infrastructure: design, implement and test the mechanisms for garbage collection or data migration to archival storage

* Design, implement and test a sharding library before you have invested much into your application deployment and make sure that you keep a registry of “shards “replicated on each server

* Separate all your K/V store and related operations into your own library/API or service
There are mainly 5 types of data types supported by Redis :
 
* Strings
* Hashes
* Lists
* Sets
* Sorted Sets
We can get the array data from Redis by using the given commands :

$list = $redis ->lrange (“tutorials”, 0, 5);
print_r($list);
/*array ([0] => Mysql [1] => Mongodb [2] => Redis [3] => MySQL [4]=> PHP [5] => Mysql)*/
We can check if the Redis is running using the given commands :
try
{
   $redis = new Redis();
   $redis -> connect (‘127.0.0.1’, 6379);
   echo “Redis is running.”;
   echo “Server is running:”. $redis -> ping()
}
catch (Exception $e)
{
echo $e -> getMessage();
}
The given steps need to be followed in order to use Redis with the .Net application :
 
* Download Redis Server
* Install Redis server
* Download Redis client
* Set configuration into the Web. config File
* Use Redis client class
Redis MongoDB
It is a key-value store. It is a document type of store.
It is relatively faster. It is relatively slower.
It uses C language. It uses C++ language.
Lua is the server-side script here. JavaScript is the server-side script here.
MULTI, EXEC, DISCARD and WATCH are the foundation of transactions in Redis. They allow the execution of a group of commands in a single step, with two important guarantees :
 
* All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single isolated operation.

* Either all of the commands or none are processed, so a Redis transaction is also atomic.
Pipelining is primarily a network optimization. It essentially means the client buffers up a bunch of commands and ships them to the server in one go.

The commands are not guaranteed to be executed in a transaction. The benefit here is saving network round trip time for every command.
 
Redis is single threaded so an individual command is always atomic, but two given commands from different clients can execute in sequence, alternating between them for example.
 
Multi/exec, however, ensures no other clients are executing commands in between the commands in the multi/exec sequence.
 
Redis is actually single-threaded, which is how every command is guaranteed to be atomic. While one command is executing, no other command will run.
 
A single-threaded program can definitely provide concurrency at the I/O level by using an I/O (de)multiplexing mechanism and an event loop (which is what Redis does).

The fact that Redis operations are atomic is simply a consequence of the single-threaded event loop. The interesting point is atomicity is provided at no extra cost (it does not require synchronization between threads).
* Sharding, also known as partitioning, is splitting the data up by key. Sharding is useful to increase performance, reducing the hit and memory load on any one resource.

* While replication, also known as mirroring, is to copy all data. Replication is useful for getting a high availability of reads. If you read from multiple replicas, you will also reduce the hit rate on all resources, but the memory requirement for all resources remains the same.

Any key-value store (of which Redis is only one example) supports sharding, though certain cross-key functions will no longer work. Redis supports replication out of the box.
First Redis is single threaded but it's not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound.
 
For instance, using pipelining Redis running on an average Linux system can deliver even 1 million requests per second, so if your application mainly uses O(N) or O(log n) commands, it is hardly going to use too much CPU.
 
However, to maximize CPU usage you can start multiple instances of Redis in the same box and treat them as different servers. At some point a single box may not be enough anyway, so if you want to use multiple CPUs you can start thinking of some way to shard earlier.
 
With Redis 4.0 Redis team started to make Redis more threaded. For now this is limited to deleting objects in the background, and to blocking commands implemented via Redis modules. For future releases, the plan is to make Redis more and more threaded.
* A program is CPU bound if it would go faster if the CPU were faster, i.e. it spends the majority of its time simply using the CPU (doing calculations). A program that computes new digits of π will typically be CPU-bound, it's just crunching numbers.
 
* A program is I/O bound if it would go faster if the I/O subsystem was faster. Which exact I/O system is meant can vary; I typically associate it with disk, but of course networking or communication in general is common too. A program that looks through a huge file for some data might become I/O bound, since the bottleneck is then the reading of the data from disk (actually, this example is perhaps kind of old-fashioned these days with hundreds of MB/s coming in from SSDs).
 
* Memory bound means the rate at which a process progresses is limited by the amount memory available and the speed of that memory access. A task that processes large amounts of in memory data, for example multiplying large matrices, is likely to be Memory Bound.
 
* Cache bound means the rate at which a process progress is limited by the amount and speed of the cache available. A task that simply processes more data than fits in the cache will be cache bound.
 
It's not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound.
We can use the two commands given below for emptying the database :
 
* FLUSHALL : It will remove the data from all databases. The syntax is given below :
Redis-CLI flushall
* FLUSHDB : It will remove all the data from the database that is currently in use by the user. The syntax is given below :
Redis-CLI flushdb
Some of the Redis commands and their descriptions are given below :
 
AUTH : It authenticates to the server.

APPEND : It appends a value to the key.

BITCOUNT : It counts set bits in a string.

BGSAVE : It saves the dataset asynchronously to disk.

CLIENT LIST : It gets the client connections list.

BGREWRITEAOF : It re-writes the append-only file asynchronously.

CLUSTER INFO : It provides information about the cluster node state of Redis.
Hashes are sort of like a key value store within a key value store. They map between string fields and string values. Field->value maps using a hash are slightly more space efficient than key->value maps using regular strings.
 
Hashes are useful as a namespace, or when you want to logically group many keys. With a hash you can grab all the members efficiently, expire all the members together, delete all the members together, etc. Great for any use case where you have several key/value pairs that need to grouped.
 
One example use of a hash is for storing user profiles between applications. A redis hash stored with the user ID as the key will allow you to store as many bits of data about a user as needed while keeping them stored under a single key. The advantage of using a hash instead of serializing the profile into a string is that you can have different applications read/write different fields within the user profile without having to worry about one app overriding changes made by others (which can happen if you serialize stale data).
Snapshot takes the data as it exists at one moment in time & writes it to the disk, will be written to the file referenced as “dbfilename”.
 
There are 5 steps to initiate snapshots.
 
BGSAVE : When redis client initiate BGSAVE, redis will create a fork so that child process will write a the snapshot to the disk where master interacts with commands.
 
SAVE : When redis client initiate SAVE, redis will stop responding any commands until snapshot completes
 
From Configuration Files:
 
Example : Configuration as SAVE 60 10000
 
BGSAVE will be called if 10000 writes occure within 60 seconds
 
SHUTDOWN : When redis client sends a SHUTDOWN, redis will perform SAVE operations, blocks all operations, shutdowns later.
 
Sync with other Redis : If a Redis server connects to another server, it issues SYNC, then master Redis will start BGSAVE.
AOF copies incoming write command to disk as they happen. It provides file synch options as follows.
 
always : Every writes to redis, writes to disk which usually affect redis’ performance.
 
b. everysec : Writes to disk every second
 
no : Let OS control syncing to disk
Sorted Sets are also collections of unique values. These ones, as the name implies, are ordered. They are ordered by a score, then lexicographically.
 
This data type is optimized for quick lookups by score. Getting the highest, lowest, or any range of values in between is extremely fast.
 
If you add users to a sorted set along with their high score, you have yourself a perfect leader-board. As new high scores come in, just add them to the set again with their high score and it will re-order your leader-board. Also great for keeping track of the last time users visited and who is active in your application.
 
Storing values with the same score causes them to be ordered lexicographically (think alphabetically). This can be useful for things like auto-complete features.
 
Many of the sorted set commands are similar to commands for sets, sometimes with an additional score parameter. Also included are commands for managing scores and querying by score.
Redis commands can fail during a transaction, but still Redis will execute the rest of the transaction instead of rolling back.
 
There are good opinions for this behavior :
 
* Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.

* Redis is internally simplified and faster because it does not need the ability to roll back.
A Redis ZSET contains unique members (the keys) and scores (confined to values of floating-point numbers). The items in a ZSET are sorted and accessible by scores and the order by which the items in the ZSET were sorted. This differs from a hash because hashes can only be accessed by scores.
 
Begin working with this guide by opening Redis and creating a sample database. Let’s start with the first section below that shows what the Redis ZSET ZADD command can do.
 
Use the Redis Zadd Command :

When you want to add unique members that have different scores and store them in your Redis database, use the ZADD Redis command like this:
127.0.0.1:6379> ZADD "id" 1 "Mark"
(integer) 1
127.0.0.1:6379> ZADD "id" 2 "Arthur"
(integer) 1
127.0.0.1:6379> ZADD "id" 3 "Monica"
(integer) 1
127.0.0.1:6379> ZADD "id" 4 "Daniel"
(integer) 1
127.0.0.1:6379> ZADD "id" 5 "Sergio"
(integer) 1
Use the Redis Zrange Command :

There may be times when you’ll want to fetch just one score value.
 
*Use the Redis ZSET command ZRANGE and identify that score by its order position.
127.0.0.1:6379> ZRANGE "id" 0 0
1) "Mark"
Use the Redis Zset to Get All the Values Stored :

The ZRANGE ZSET command returns a range of scores sorted from low to high.
 
Use ZRANGE to display every score in a Redis ZSET like this:
127.0.0.1:6379> ZRANGE "id" 0 -1
1) "Mark"
2) "Arthur"
3) "Monica"
4) "Daniel"
5) "Sergio"
You can also use the ZRANGE command to show all of the elements of a sorted ZSET using the WITHSCORES option as shown here:
127.0.0.1:6379> ZRANGE "id" 0 -1 WITHSCORES
 1) "Mark"
 2) "1"
 3) "Arthur"
 4) "2"
 5) "Monica"
 6) "3"
 7) "Daniel"
 8) "4"
 9) "Sergio"
10) "5"
Using the Redis Zrangebyscore Command : Fine-tune your results by inputting your desired members range by using the Redis ZSET command ZRANGEBYSCORE.
 
The ZRANGEBYSCORE command displays every element in a set based on a score range when you specify a minimum and maximum number as shown in this example here:
127.0.0.1:6379> ZRANGEBYSCORE "id" 0 2
1) "Mark"
2) "Arthur"
Try out the ZRANGEBYSCORE command with the WITHSCORES option like this :
127.0.0.1:6379> ZRANGEBYSCORE "id" 0 2 withscores
1) "Mark"
2) "1"
3) "Arthur"
4) "2"
Deleting data that is no longer needed is a common maintenance task you perform on a regular basis.
 
Use the ZREM Redis ZSET command to delete a member and score in a ZSET like this :
127.0.0.1:6379> ZREM "id" "Mark"
(integer) 1
127.0.0.1:6379> ZREM "id" "Mark"
(integer) 0
In the example above, the ZREM command removed the ZSET item. You can tell because it looked for the member and score again and 0 was returned. This shows that you have successfully removed the item from the ZSET. If you look for the item again, a 0 will display in the results.
The list operations are given below :
 
LPOP : An element is removed from the head by it.

RPOP : An element is removed from the tail by it.

LPUSH : A new element is inserted on the head by this operation.

RPUSH : A new element is inserted on the head by this operation.

LRANGE : An element is printed from the specified position


Example :
 
127.0.0.1:6379> LPUSH A 1
 
127.0.0.1:6379> RPUSH A 2
 
127.0.0.1:6379> RPUSH A 3
 
127.0.0.1:6379> RPUSH A 4
 
127.0.0.1:6379> LRANGE A 0 -1
 
1) "1"
 
2) "2"
 
3) "3"
 
4) "4"
 
127.0.0.1:6379> LPOP A
 
"1" ["1" element value is removed]
 
127.0.0.1:6379> LRANGE A 0 -1
 
1) "2"
 
2) "3"
 
3) "4"
 
127.0.0.1:6379> RPOP A
 
"4" ["4" element value is removed]
 
127.0.0.1:6379> LRANGE A 0 -1
 
1) "2"
 
2) "3"
The SET operations are given below :

SMEMBERS : Values from the KEY are retrieved.

SADD : A new element is added to the set.

SISMEMBER : The presence of a specified element is verified in the SET.

SPOP : The element is popped out from the SET.

Example :
 
127.0.0.1:6379> SADD TEST_SET A

(integer) 1

127.0.0.1:6379> SADD TEST_SET B

(integer) 1

127.0.0.1:6379> SMEMBERS TEST_SET

1) "A"

2) "B"

127.0.0.1:6379> SISMEMBER TEST_SET A

(integer) 1 [1 indicates it's true; it's available]

127.0.0.1:6379> SPOP TEST_SET

"A"

127.0.0.1:6379> SMEMBERs TEST_SET

1) "B"
40 .
How can you enhance the durability of Redis?
Whenever a new command is added to the append log file, call Fsysnc() each time.

Keep calling Fsysnc() in every second. Despite of the 1 second data lose in the case of system fails.
SUNTIONSTORE : This command resembles the SUNION command, but the resulting set is stored in the destination instead of getting returned.
 
SINTERSTORE : This command resembles the SINTER command, but again the resulting set is stored in the destination instead of getting returned.
42 .
Files will keep on growing as long as AOF executed. Won’t it consume more memory? What is the solution provided by redis?
Redis provides command BGREWRITEAOF which rewrites the existing AOF with the shortest sequence of commands needed to rebuild the current dataset in memory.
Redis Strings are binary safe, this means that a Redis string can contain any kind of data, for instance a JPEG image or a serialized Ruby object.
 
A String value can be at max 512 Megabytes in length.
SET command used to set a value to the key and GET command to get a value of the key as follows, of data-type STRING.
127.0.0.1:6379> SET TEST_KEY TEST_VALUE

OK [TEST_VALUE is being set to TEST_KEY]

127.0.0.1:6379> GET TEST_KEY

"TEST_VALUE"
SET Command with NX|XX arguments
 
NX argument indicates that SET a value to the key if the key is not exist;
 
XX argument indicates that SET a value to the key only if the key already exists;
 
Example:
 
NX: key TEST_KEY is already exist; If we try to update TEST_KEY value, it will not accept and returns (nill) status
127.0.0.1:6379> SET TEST_KEY TEST_VALUE_UPDATED NX

(nil)

127.0.0.1:6379> GET TEST_KEY

"TEST_VALUE"
Value of TEST_KEY remain same;
 
XX: key TEST_KEY is alrady exists; Hence so, when we try to udpate TEST_KEY value, its updated and ack OK
127.0.0.1:6379> SET TEST_KEY TEST_VALUE_XX_UDPATED XX

OK

127.0.0.1:6379> GET TEST_KEY

"TEST_VALUE_XX_UDPATED"
Internal Implementation : Linked-List
 
Redis Lists are simply lists of strings, sorted by insertion order. It is possible to add elements to a Redis List pushing new elements on the head (on the left) or on the tail (on the right) of the list.
 
The max length of a list is 2³² — 1 elements (4294967295, more than 4 billion of elements per list).
This is a case when you want to do remove operations like RPOP/LPOP, but the list is already empty. In this case, remove operation will return null does nothing. In this case a consumer is forced to wait some time and retry again with RPOP.
 
So Redis implements commands called BRPOP and BLPOP which are versions of RPOP and LPOP able to block if the list is empty: This will return to the caller only when a new element is added to the list, or when a user-specified timeout is reached.
 
Example : If we want pop the elements from the list A, which is empty right now;
127.0.0.1:6379> brpop A {timeout}

...

...​

 

waits until new elements is added to list key A
 
timeout : No of seconds to wait until; 0 indicates wait forever
Redis Sets are an unordered collection of Strings. It is possible to add, remove, and test for existence of members in O(1)
 
The max number of members in a set is 2³² — 1 (4294967295, more than 4 billion of members per set).
SUNION : The members of the set are returned from the union of all the sets that are given.
 
SINTER : The members of the set are returned that result from the intersection of all the sets that are given.

Example :
127.0.0.1:6379> SMEMBERS TEST_KEY_A

1) "1"

2) "2"

3) "3"

127.0.0.1:6379> SMEMBERS TEST_KEY_B

1) "2"

2) "6"

127.0.0.1:6379> SUNION TEST_KEY_A TEST_KEY_B

1) "1"

2) "2"

3) "3" [prints union of two sets]

4) "6"

127.0.0.1:6379> SINTER TEST_KEY_A TEST_KEY_B

1) "2" [print intersection of two sets]
49 .
We all know that Reds is fast, but is it also durable?
In Redis, there is always a trade-of between durability and speed. In the case of system failure, it may lose data which is not stored.
ZADD : Adds all the specified members with the specified scores to the sorted set stored at key.
 
Time complexity : O(log(N)) for each item added, where N is the number of elements in the sorted set.
 
ZREM : Removes the specified members from the sorted set stored at key. Non existing members are ignored.
 
Time complexity : O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.
 
ZRANGE : Returns the specified range of elements in the sorted set stored at key.
 
Time complexity : O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.
 
ZRANGEBYSCORE : Returns all the elements in the sorted set at key with a score between min and max.
 
Time complexity : O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).
 
127.0.0.1:6379> ZADD TEST_ZKEY 1 A

(integer) 1

127.0.0.1:6379> ZADD TEST_ZKEY 2 B

(integer) 1

127.0.0.1:6379> ZADD TEST_ZKEY 1 C

(integer) 1

127.0.0.1:6379> ZRANGE TEST_ZKEY 0 -1

1) "A"

2) "C"

3) "B"

127.0.0.1:6379> ZREM TEST_ZKEY B

(integer) 1

127.0.0.1:6379> ZRANGE TEST_ZKEY 0 -1

1) "A"

2) "C"

127.0.0.1:6379> ZRANGEBYSCORE TEST_ZKEY 1 2 {Here 1 is min rank, 2 is max rank- gets a data from rank of 1 to 2}

1) "A"
Redis is not usually deployed as a "durable" datastore (in the sense of the "D" in ACID.), even with journaling. Most use cases intentionally sacrifice a little durability in return for speed.
 
However, the "append only file" storage mode can optionally be configured to operate in a durable manner, at the cost of performance. It will have to pay for an fsync() on every modification.
Rough results are 2x write, 3x read.

The general answer is that Redis 10 - 30% faster when the data set fits within working memory of a single machine. Once that amount of data is exceeded, Redis fails.

But your best bet is to benchmark them yourself, in precisely the manner you are intending to use them. As a corollary you'll probably figure out the best way to make use of each.
Your options are as follows :
 
* Using LREM and replacing it if it was found.

* Maintaining a separate SET in conjunction with your LIST

* Looping through the LIST until you find the item or reach the end.

Redis lists are implemented as a, hence the limitations. I think your best option is maintaining a duplicate SET. Regardless, make sure your actions are atomic with MULTI-EXEC or Lua scripts.
Here is the underlying implementation of every Redis data type.
 
* Strings are implemented using a C dynamic string library so that we don't pay (asymptotically speaking) for allocations in append operations. This way we have O(N) appends, for instance, instead of having quadratic behavior.

* Lists are implemented with linked lists.

* Sets and Hashes are implemented with hash tables.

* Sorted sets are implemented with skip lists (a peculiar type of balanced trees).

* Zip List

* Int Sets

* Zip Maps (deprecated in favour of zip list since Redis 2.6)

It shall be also said that for every Redis operation you'll find the time complexity in the documentation so if you are not interested in Redis internals you should not care about how data types are implemented internally really.
Redis will either be killed by the Linux kernel OOM killer, crash with an error, or will start to slow down. With modern operating systems malloc() returning NULL is not common, usually the server will start swapping (if some swap space is configured), and Redis performance will start to degrade, so you'll probably notice there is something wrong.
 
Redis has built-in protections allowing the user to set a max limit to memory usage, using the maxmemory option in the configuration file to put a limit to the memory Redis can use. If this limit is reached Redis will start to reply with an error to write commands (but will continue to accept read-only commands), or you can configure it to evict keys when the max memory limit is reached in the case where you are using Redis for caching.