<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sumit kumar</title>
    <description>The latest articles on DEV Community by sumit kumar (@sksam284).</description>
    <link>https://dev.to/sksam284</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F790122%2F6bb69f2e-c9a9-498d-ac74-ee28d79d5075.jpeg</url>
      <title>DEV Community: sumit kumar</title>
      <link>https://dev.to/sksam284</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sksam284"/>
    <language>en</language>
    <item>
      <title>Cache Master data in Redis using Python</title>
      <dc:creator>sumit kumar</dc:creator>
      <pubDate>Wed, 12 Jan 2022 12:42:45 +0000</pubDate>
      <link>https://dev.to/epam_india_python/cache-master-data-in-redis-using-python-2pd3</link>
      <guid>https://dev.to/epam_india_python/cache-master-data-in-redis-using-python-2pd3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;According to its &lt;a href="https://github.com/redis/redis" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;, Redis (stands for &lt;strong&gt;RE&lt;/strong&gt;mote &lt;strong&gt;DI&lt;/strong&gt;ctionary &lt;strong&gt;S&lt;/strong&gt;erver) is an in-memory data structure store. It is a disk-persistent key-value database with support for multiple data structures such as strings, hashes, lists, sets, bitmaps, etc.&lt;/p&gt;

&lt;p&gt;Data structures implemented into Redis have a few special properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis cares to store them on disk, even if they are always served and modified into the server memory. This means that Redis is fast, but that it is also non-volatile.&lt;/li&gt;
&lt;li&gt;The implementation of data structures emphasizes memory efficiency, so data structures inside Redis will likely use less memory compared to the same data structure modelled using a high-level programming language.&lt;/li&gt;
&lt;li&gt;Redis offers a number of features that are natural to find in a database, like replication, durability, clustering, and high availability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;p&gt;When speaking of use cases of using Redis, the most generic use case that comes to many is for caching data and for session store (i.e. web session). Redis has a lot of use cases that can be applied and useful for any situations especially that involves speed and scalability wise, it's easy to manage either scaling up or scaling down.&lt;/p&gt;

&lt;p&gt;Few use cases are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Session store&lt;/li&gt;
&lt;li&gt;Chat and messaging application&lt;/li&gt;
&lt;li&gt;Gaming leader board applications&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Caching Data in Redis
&lt;/h2&gt;

&lt;p&gt;The cache is temporary storage where data is stored so that in the future data can be accessed faster. So, caching is the process of storing data in Cache. One of the caching use cases is caching the master data that can be database query results, pandas data frame, etc. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;br&gt;
Install python and Redis. Following versions are used in this blog:&lt;/p&gt;

&lt;p&gt;python==3.9.0&lt;/p&gt;

&lt;p&gt;redis==4.1.0&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/redis/" rel="noopener noreferrer"&gt;redis-py&lt;/a&gt; requires a running Redis server, and Python 3.6+. See the &lt;a href="https://redis.io/topics/quickstart" rel="noopener noreferrer"&gt;Redis quickstart&lt;/a&gt; for Redis installation instructions.&lt;/p&gt;

&lt;p&gt;redis-py can be installed using pip via “pip install redis”.&lt;/p&gt;

&lt;p&gt;To test that the Redis connection to the server is successful, we can open a new terminal window and run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;% redis-cli ping&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The output should be&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PONG&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create instance of Redis Class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We need to create instance of Redis class that expects mainly Redis broker URL, port, and database, and it can be further used to do all CRUD operations on Redis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsb8ttu8jrpasbxajocc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsb8ttu8jrpasbxajocc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key-Value storage&lt;/strong&gt;&lt;br&gt;
Cache is maintained in key-value pair, which means we can store any data with respect to a unique key like dictionary. Here key can be any string with max size of 512 MB. Values, on the other hand, can vary in size depending on their type. For aggregate data types (i.e. hash, list, set, and sorted set), the maximum value size is 512 MB for each element, although the data structure itself can have up to 2^32 - 1 elements.&lt;/p&gt;

&lt;p&gt;Data structures supported in values by Redis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Binary-safe strings&lt;/li&gt;
&lt;li&gt;Lists&lt;/li&gt;
&lt;li&gt;Sets&lt;/li&gt;
&lt;li&gt;Sorted sets&lt;/li&gt;
&lt;li&gt;Hashes&lt;/li&gt;
&lt;li&gt;Bit arrays (or simply bitmaps)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Redis can handle up to 232 keys and was tested in practice to handle at least 250 million keys per instance.&lt;/p&gt;

&lt;p&gt;Every hash, list, set, and sorted set, can hold 232 elements.&lt;/p&gt;

&lt;p&gt;In other words, your limit is likely the available memory in your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check if key exist in Redis&lt;/strong&gt;&lt;br&gt;
Since data is saved in Redis as key-value pair, we can check if key is already there in cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.exists(key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if not app_redis_handler.exists("balance"):
    return None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create cache using key&lt;/strong&gt;&lt;br&gt;
We can create a cache based on provided key and value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.set(key, data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.set("balance",1777)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Save json dictionary as value&lt;/strong&gt;&lt;br&gt;
We can also save json as data in Redis cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.set(key, json.dumps(data))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.set("balance", json.dumps({"due":577,\
 "credit":680}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Set expiry on Cache key&lt;/strong&gt;&lt;br&gt;
We can provide expiry of cache key in seconds. Keys expiring information is stored as absolute Unix timestamps (in milliseconds in case of Redis version 2.6 or greater).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.expire(key, expiry)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.expire("balance", 10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create cache using key with expiry&lt;/strong&gt;&lt;br&gt;
We can create a cache based on provided key and value along with expiry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.setex(key, expiry, data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.setex("balance",60, 1777)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Get data based on key&lt;/strong&gt;&lt;br&gt;
Value can be fetched from cache based on key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = app_redis_handler.get(key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = app_redis_handler.get("balance")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete/invalidate data based on key:&lt;/strong&gt;&lt;br&gt;
Delete/invalidate cache key once not required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.delete(key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.delete("balance")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scan all keys prefixed with "prefix_text":&lt;/strong&gt;&lt;br&gt;
Cache key is searchable based on prefix, and it fetches all keys prefixed with the provided text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;redis_handler.scan_iter(f'{prefix_text}*')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[key for key in app_redis_handler.scan_iter(f'{bal}*')]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Save master data in cache&lt;/strong&gt;&lt;br&gt;
We can also save the master data that can be database query results, pandas data frame data, etc. in cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_redis_handler.set("employee", [(1, 'John', 'Finance'), \
(2, 'Richard', 'Energy'), (3, 'Carter', 'HR'),……])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we can save the master data in cache, and fetch it whenever required and load it in data frame like structure to apply filters like "department=HR". It can be useful if we want to show top employees of all departments from cache, so it is better to save it in one cache and apply filter on cache data to save the extra transactions to database and managing the extra keys in cache.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Redis offers highly performant and efficient read and write along with few operations mentioned in this article. There are lots more. For more information, you can visit the &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://redis.io" rel="noopener noreferrer"&gt;https://redis.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/redis/redis" rel="noopener noreferrer"&gt;https://github.com/redis/redis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://redis-py.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;https://redis-py.readthedocs.io/en/stable/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kite.com/python/docs/redis.StrictRedis" rel="noopener noreferrer"&gt;https://www.kite.com/python/docs/redis.StrictRedis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is a personal blog/post. The views and opinions expressed here are only those of the author and do not represent those of any organization or any individual with whom the author may be associated, professionally or personally.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>caching</category>
      <category>python</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
