<?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: elysianx</title>
    <description>The latest articles on DEV Community by elysianx (@elysianx138).</description>
    <link>https://dev.to/elysianx138</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3995339%2F30d1bfaf-a649-496b-9386-8bc2a8d7655d.png</url>
      <title>DEV Community: elysianx</title>
      <link>https://dev.to/elysianx138</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elysianx138"/>
    <language>en</language>
    <item>
      <title>How to Start Docker for Beginners</title>
      <dc:creator>elysianx</dc:creator>
      <pubDate>Fri, 03 Jul 2026 14:00:38 +0000</pubDate>
      <link>https://dev.to/elysianx138/how-to-start-docker-for-beginners-331i</link>
      <guid>https://dev.to/elysianx138/how-to-start-docker-for-beginners-331i</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6xiqrvnk4d0fxgfa5433.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6xiqrvnk4d0fxgfa5433.png" alt=" " width="222" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Docker
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Docker is a containerization platform that packages applications with all dependencies into portable utils called containers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Learn the foundational concepts of &lt;code&gt;Docker&lt;/code&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Core concepts:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt;: A read-only blueprint containing app code,libraries,and environment settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container&lt;/strong&gt;: A running instance of an image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dockerfile&lt;/strong&gt;: Script defining how to build an image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume&lt;/strong&gt;: Persistent storage outside the container lifecycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt;: Enables communication between containers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Example: Building and Running a Container&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM node:18
WORKDIR /app
COPY package.json ./
RUN npm &lt;span class="nb"&gt;install
&lt;/span&gt;COPY &lt;span class="nb"&gt;.&lt;/span&gt;
EXPOSE 3000
CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"npm"&lt;/span&gt;, &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-node-app

docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 my-node-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Managing Multi-Container Apps with Docker Compose
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;version: &lt;span class="s1"&gt;'3'&lt;/span&gt;
services:
 app:
   build:
   ports:
     - &lt;span class="s2"&gt;"3000:3000"&lt;/span&gt;
   depends_on:
     - mongo
 mongo:
   image: mongo
   volumes:
     - mongo-data:/data/db
volumes:
 mongo-data:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RUN with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Best Practices
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;.dockerignore&lt;/code&gt; to exclude unnecessary files(e.g.,&lt;code&gt;.git&lt;/code&gt;,&lt;code&gt;node_modules&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;:latest&lt;/code&gt; tags;pin versions for stability.&lt;/li&gt;
&lt;li&gt;Run containers as non-root for security.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;multi-stage builds&lt;/strong&gt; to reduce image size.&lt;/li&gt;
&lt;li&gt;Store secrets in &lt;code&gt;.env&lt;/code&gt; files or Docker secrets, not in images.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  When to Use Docker
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;[Y] Consistent dev/prod environments&lt;/li&gt;
&lt;li&gt;[N] Small static sites or quick scripts where setup overhead outweighs benefits.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Next Steps
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Learn &lt;strong&gt;Docker networking&lt;/strong&gt;(bridge, host, overlay)for container communication.&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;Docker volumes&lt;/strong&gt; for persistent data.&lt;/li&gt;
&lt;li&gt;Integrate Docker into &lt;strong&gt;CI/CD pipelines&lt;/strong&gt; for automated builds and deployments.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;With these fundamentals, you can confidently containerize, run, and manage applications in any environment.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>backend</category>
      <category>learning</category>
    </item>
    <item>
      <title>How to Submit the First Formal PR for Beginners?</title>
      <dc:creator>elysianx</dc:creator>
      <pubDate>Thu, 02 Jul 2026 13:39:35 +0000</pubDate>
      <link>https://dev.to/elysianx138/how-to-submit-the-first-formal-pr-for-beginners-1gk3</link>
      <guid>https://dev.to/elysianx138/how-to-submit-the-first-formal-pr-for-beginners-1gk3</guid>
      <description>&lt;p&gt;After spending some time contributing  to open source,I’ve realized the biggest hurdle for beginners isn’t finding a sustainable project-it’s submitting your first PR. If you’re also a beginner aiming to create your first PR, keep reading. &lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1:Prepare
&lt;/h2&gt;

&lt;h4&gt;
  
  
  If you don't have git on your machine, &lt;a href="https://docs.github.com/en/get-started/quickstart/set-up-git" rel="noopener noreferrer"&gt;install it&lt;/a&gt;.
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Step 2:Fork this repository
&lt;/h2&gt;

&lt;p&gt;Fork this repository by clicking on the fork button on the top of this page.&lt;br&gt;
This will create a copy of this repository in your account.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3:Clone the repository
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffirstcontributions.github.io%2Fassets%2FReadme%2Fclone.png" class="article-body-image-wrapper"&gt;&lt;img width="388" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffirstcontributions.github.io%2Fassets%2FReadme%2Fclone.png" alt="clone the repository" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now clone the forked repository to your machine. Go to your GitHub account, open the forked repository, click on the code button, then on SSH tab and then click the &lt;em&gt;copy url to clipboard&lt;/em&gt; icon.&lt;/p&gt;

&lt;p&gt;Open a terminal and run the following git command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="s2"&gt;"url you just copied"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4:Find a &lt;code&gt;good-first-issue&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now search for an issue you like&lt;/p&gt;

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

&lt;p&gt;Communicate with the maintainer about what you should do! Don't worry you can't do it well. You will be assigned, then work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5:Create a branch
&lt;/h2&gt;

&lt;p&gt;Change to the repository directory on your computer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-first-contributions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Make necessary changes and commit those changes
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;Contributors.md&lt;/code&gt; file in a text editor and issue,add your name to it.Save your file.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffirstcontributions.github.io%2Fassets%2FReadme%2Fgit-status.png" class="article-body-image-wrapper"&gt;&lt;img width="799" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffirstcontributions.github.io%2Fassets%2FReadme%2Fgit-status.png" alt="git status" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you go to the project directory and execute the command &lt;code&gt;git status&lt;/code&gt;, you'll see there are changes.&lt;/p&gt;

&lt;p&gt;Add those changes to the branch you just created using the &lt;code&gt;git add&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add Contributors.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now commit those changes using the &lt;code&gt;git commit&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add your-name to Contributors list"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;replacing &lt;code&gt;your-name&lt;/code&gt; with your name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push changes to GitHub
&lt;/h2&gt;

&lt;p&gt;Push your changes using the command &lt;code&gt;git push&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin your-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;replacing &lt;code&gt;your-branch-name&lt;/code&gt; with the name of the branch you created earlier.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Communicate with the maintainer about what to do. Don't worry if it's not perfect — they'll guide you. Get assigned, then get to work.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>I Build a blog API with Redis - Here's every problem I Hit</title>
      <dc:creator>elysianx</dc:creator>
      <pubDate>Tue, 23 Jun 2026 14:21:13 +0000</pubDate>
      <link>https://dev.to/elysianx138/i-build-a-blog-api-with-redis-heres-every-problem-i-hit-gjj</link>
      <guid>https://dev.to/elysianx138/i-build-a-blog-api-with-redis-heres-every-problem-i-hit-gjj</guid>
      <description>&lt;p&gt;I build a blog API with FastAPI + Redis + MySQL.&lt;br&gt;
Three cache problems almost killed my app.&lt;br&gt;
If you also face these problems!&lt;br&gt;
Here's how I fixed each one.&lt;/p&gt;


&lt;h1&gt;
  
  
  1. Cache Penetration
&lt;/h1&gt;
&lt;h2&gt;
  
  
  What's Cache Penetration?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cache Penetration&lt;/strong&gt; refers to a scenario where the requested data exists neither in cache nor in the database,causing every request to hit the database directly,thereby increasing the database load.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to solve?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1.Caching null values
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a queried key exists in neither the cache nor the database,the result (such as &lt;code&gt;null&lt;/code&gt; or an empty value) is cached with a short TTL.&lt;/li&gt;
&lt;li&gt;This way,subsequent identical requests can be served directly from the cache,avoiding frequent database access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_redis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# First, check the cache. If the cache entry exists, check whether it is __NULL__
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__NULL__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Second, cache miss, query database
&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Third, cache the result whether it exists in DB or not
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;# cache real data
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__NULL__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# cache null sentinel (short TTL)
&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  2.Cache breakdown
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What's Cache breakdown?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cache breakdown&lt;/strong&gt;occurs when a popular data entry expires in the cache while a massive number of concurrent requests are hitting that same data at the exact same time.All those requests penetrate straight through to the database,putting enormous pressure on it and potentially causing system performance issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lock mechanism:&lt;/strong&gt;When the cache expires,use a locking mechanism to ensure that only one thread can access the database and update the cache.The other threads wait util the cache is rebuilt before reading the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Generate a lock key based on the given key
&lt;/span&gt;&lt;span class="n"&gt;lock_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mutex:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Use SETNX operation to acquire the lock. If the key does not exist, set it with an expiration time of 300 seconds.
# This prevents concurrent access.
&lt;/span&gt;&lt;span class="n"&gt;lock_acquired&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lock_acquired&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Successfully acquired the lock, query the database
&lt;/span&gt;        &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;db_query_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Write the result to the cache with an expiration time of 3600 seconds
&lt;/span&gt;            &lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Release the lock
&lt;/span&gt;        &lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Failed to acquire the lock, sleep for 0.1 seconds and then retry
&lt;/span&gt;    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;get_data_with_mutex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_query_func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  3.Cache avalanche
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What's cache avalanche?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cache avalance&lt;/strong&gt;refers to a situation where a large amount of cached data expires at the same time or the cache service goes down. As a result, all requests are directly sent to the database, causing a sudden surge in the database's pressure and even leading to its downtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Randomized TTL&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The core idea is to avoid a large number of keys expiring simultaneously.&lt;/li&gt;
&lt;li&gt;When setting the expiration time for the cache, add a random value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;

&lt;span class="n"&gt;expire_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;expire_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What about you?
&lt;/h2&gt;

&lt;p&gt;Have you run into any of these cache problems in your projects? &lt;br&gt;
Or do you use a different strategy? Let me know in the comments 👇&lt;/p&gt;

&lt;p&gt;If this was helpful, follow me for more backend deep dives.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>fastapi</category>
      <category>python</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
