<?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: zhengxin</title>
    <description>The latest articles on DEV Community by zhengxin (@zhengxin).</description>
    <link>https://dev.to/zhengxin</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%2F1224404%2Fe94a1efe-101f-4d67-8703-4ca4ec0023fb.png</url>
      <title>DEV Community: zhengxin</title>
      <link>https://dev.to/zhengxin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhengxin"/>
    <language>en</language>
    <item>
      <title>Kubernetes Cluster as an OpenID Connect Identity Provider</title>
      <dc:creator>zhengxin</dc:creator>
      <pubDate>Sat, 02 Dec 2023 14:29:57 +0000</pubDate>
      <link>https://dev.to/zhengxin/kubernetes-cluster-as-an-openid-connect-identity-provider-bpn</link>
      <guid>https://dev.to/zhengxin/kubernetes-cluster-as-an-openid-connect-identity-provider-bpn</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Traditionally, when executing programs or applications on Virtual Machines (VMs) provided by cloud services, the cloud provider grants specified permissions to the VM. This setup allows the program running on the VM to access designated cloud resources without the need for password authentication. For instance, in Azure, binding a system-assigned or user-assigned managed identity to a VM enables the program running on the VM to operate as the managed identity, inheriting permissions associated with it.&lt;/p&gt;

&lt;p&gt;We aim to replicate this user experience in Kubernetes, whereby a pod in a Kubernetes cluster (k8s) can be granted permissions without requiring the program within the pod to read any long-term credentials like passwords.&lt;/p&gt;

&lt;p&gt;Previously, Azure Kubernetes Service (AKS) had introduced a feature known as &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity"&gt;Pod Identity&lt;/a&gt; to achieve this. However, this feature was deprecated before reaching General Availability (GA) as a more robust and widely accepted solution emerged.&lt;/p&gt;

&lt;p&gt;The feature, &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-issuer-discovery"&gt;Service Account Issuer Discovery&lt;/a&gt;, marked as stable starting from Kubernetes version v1.21, transforms the Kubernetes API server into an OIDC identity provider. This setup facilitates the issuance of tokens, via service accounts to pods, which are recognizable by external services outside the Kubernetes cluster, thereby establishing an authentication pathway between the pod within the cluster and external services including those on Azure, AWS, etc.&lt;/p&gt;

&lt;p&gt;Both Azure AKS and AWS EKS have enabled this feature by default, offering convenient methods to configure the Kubernetes cluster OIDC Provider to integrate with their respective access control services, namely Microsoft Entra ID and AWS IAM. This feature is termed differently in their respective managed cluster documentation as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AKS: &lt;a href="https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview?tabs=dotnet"&gt;Workload Identity&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;EKS: &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html"&gt;IAM roles for service accounts (IRSA)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: All Kubernetes clusters with the "Service Account Issuer Discovery" feature enabled can be integrated with cloud providers, not merely the managed clusters provided by cloud providers, albeit the setup may be slightly complex.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this document, we will delve into the workings of this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service Account Issuer Discovery Flow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oB_s4Vve--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6afUzhF.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oB_s4Vve--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6afUzhF.jpg" alt="" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assume we have a Kubernetes cluster, hosting applications purposed for reading and writing Azure Blobs.&lt;/p&gt;

&lt;p&gt;Initially, the cluster administrator should activate the "Service Account Issuer Discovery" feature on the cluster. Following this, the cluster should be configured with the cloud provider, in this instance, Microsoft Entra ID, ensuring that Microsoft Entra ID is cognizant of the cluster's existence. In more precise terms, Microsoft Entra ID and the Kubernetes OIDC provider are federated, establishing a trust relationship.&lt;/p&gt;

&lt;p&gt;Applications running in the cluster are assigned service accounts. (If not explicitly defined, a default service account is bound to every pod). Assigning a service account to a pod results in a JWT token being projected into the pod, stored on the pod’s disk.&lt;/p&gt;

&lt;p&gt;Through different annotations on the service account, the cluster administrator can manipulate the claims within the token, thus, various service accounts can be endowed with different permissions.&lt;/p&gt;

&lt;p&gt;The application can read the JWT token and forward it to the cloud access control service, in this scenario, Microsoft Entra ID. Upon receiving the token, Microsoft Entra ID validates it. Given the pre-established trust relationship with the Kubernetes cluster OIDC provider, it can ascertain the token’s validity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: In this step, the cloud access control service may or may not access the Kubernetes API server, depending on whether the JWT token validation is a local or remote process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Post validation, Microsoft Entra ID issues an access token to the application. The application can then utilize this token to access Azure Blobs or other cloud resources managed by Microsoft Entra ID.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview?tabs=dotnet"&gt;Use Microsoft Entra ID Workload Identity with Azure Kubernetes Service (AKS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-issuer-discovery"&gt;Service Account Issuer Discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html"&gt;IAM roles for service accounts (IRSA)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>oauth</category>
      <category>oidc</category>
    </item>
    <item>
      <title>Understand Windows Azure Storage Architecture</title>
      <dc:creator>zhengxin</dc:creator>
      <pubDate>Sat, 02 Dec 2023 14:28:54 +0000</pubDate>
      <link>https://dev.to/zhengxin/understand-windows-azure-storage-architecture-3gfn</link>
      <guid>https://dev.to/zhengxin/understand-windows-azure-storage-architecture-3gfn</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lz70-OAX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6pbX8xp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lz70-OAX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6pbX8xp.jpg" alt="taylor-vick-M5tzZtFCOfs-unsplash" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Windows Azure Storage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Windows Azure Storage (WAS)&lt;/strong&gt; is Microsoft's answer to the rising demand for robust and accessible cloud storage solutions. This service allows users to store vast amounts of data indefinitely while ensuring accessibility from anywhere at any given time. Its diverse storage options include Blobs for files, Tables for structured data, and Queues for message delivery.&lt;/p&gt;

&lt;p&gt;The strength of WAS lies in its commitment to data resilience, with features such as local and geographic replication. This ensures data remains intact, even in the face of disasters. Additionally, the system prides itself on scalability, with a partitioned global namespace allowing consistent data storage and access from any global location. Other commendable features include multi-tenancy, strong consistency, and cost-effective storage options.&lt;/p&gt;

&lt;p&gt;Delve deeper into WAS's inner workings in this &lt;a href="https://azure.microsoft.com/en-us/blog/sosp-paper-windows-azure-storage-a-highly-available-cloud-storage-service-with-strong-consistency/"&gt;SOSP Paper&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Overview of WAS's Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2kwlDyJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/MhmYCjA.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2kwlDyJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/MhmYCjA.jpg" alt="" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Within the Azure ecosystem, a user can set up one or more Storage Accounts. Each of these accounts is identifiable by a unique name. On account creation, the Location Service assigns it to a primary Storage Stamp and creates a DNS record. This action redirects the &lt;em&gt;AccountName.service.core.windows.net&lt;/em&gt; to the Virtual IP (VIP) of that Storage Stamp. Consequently, users can then communicate directly with this Storage Stamp for their storage needs.&lt;/p&gt;

&lt;p&gt;To understand the structure further, consider each Storage Stamp as a cluster of nodes, often spread across various racks within a data center. This is where Azure users will store their data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delving into the Storage Stamp
&lt;/h2&gt;

&lt;p&gt;A Storage Stamp consists of three main layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Front-Ends&lt;/strong&gt;: These act as intermediaries, receiving client requests and forwarding them to the suitable partition server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition Layer&lt;/strong&gt;: This layer processes high-level data abstractions, such as Blob, Table, and Queue. It ensures transaction sequencing and strong consistency while operating atop the stream layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stream Layer&lt;/strong&gt;: Essentially the base, this layer saves data bits on disks. It's tasked with distributing and replicating data across multiple servers, ensuring data durability within a storage stamp.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  A Closer Look at the Stream Layer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M5Ka-Xzm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/il8duc1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M5Ka-Xzm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/il8duc1.jpg" alt="" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This layer is split into two core components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stream Manager (SM)&lt;/strong&gt;: SM oversees the Extent Nodes (ENs). It's in charge of actions like generating new ENs and overseeing garbage collection. Additionally, it uses paxos to guarantee state consistency for itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extent Node (EN)&lt;/strong&gt;: Every EN governs a group of disks, maintaining the actual data storage. ENs communicate amongst themselves for the purpose of data replication.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the Partition Layer seeks to create a new data extent, it requests the SM to assign three ENs. Data is primarily sent to the primary EN, which only acknowledges a successful transaction once the data has been replicated across the secondary ENs. This intra-stamp replication is synchronized to ensure internal errors, like disk failures or power outages, don't result in data loss.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examining the Partition Layer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lC2j3Hyj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/jrcYXJR.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lC2j3Hyj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/jrcYXJR.jpg" alt="" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primarily serving the Front-Ends, the Partition Layer structures the Blob, Table, and Queue using the Stream Layer. Its two main components are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Partition Manager (PM)&lt;/strong&gt;: When Front-Ends need to create or delete an object, they use a partition key and an object name. PM then identifies the appropriate Partition Server (PS) for the request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition Server (PS)&lt;/strong&gt;: The PS collaborates with the Stream Layer to organize data and ensure consistency within its partition.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An essential task for the Partition Layer is its asynchronous replication. This feature replicates data across various stamps. Inter-stamp replication is asynchronous, happening in the background, off the critical path of the user's request. This replication method ensures data storage in diverse geographical locations, fortifying disaster recovery measures.&lt;/p&gt;

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

&lt;p&gt;Windows Azure Storage (WAS) stands as a testament to Microsoft's commitment to delivering a seamless and resilient cloud storage experience. I hope this blog can help you to have a quick understanding on its architecture, and I suggest you to take a look at the origin paper to have a better knowledge on this well-designed large scale storage system.&lt;/p&gt;

</description>
      <category>database</category>
      <category>azure</category>
      <category>storage</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Unpacking LSM-Trees: The Powerhouse Behind Modern Databases</title>
      <dc:creator>zhengxin</dc:creator>
      <pubDate>Sat, 02 Dec 2023 14:24:43 +0000</pubDate>
      <link>https://dev.to/zhengxin/unpacking-lsm-trees-the-powerhouse-behind-modern-databases-4hdo</link>
      <guid>https://dev.to/zhengxin/unpacking-lsm-trees-the-powerhouse-behind-modern-databases-4hdo</guid>
      <description>&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%2Fi.imgur.com%2FndFGZZu.jpg" 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%2Fi.imgur.com%2FndFGZZu.jpg" alt="nasa-Q1p7bh3SHj8-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Log-Structured Merge-trees (LSM-trees)&lt;/strong&gt; are virtually omnipresent in today's database systems, spanning both SQL and NoSQL architectures. They are the storage layer backbone of various high-profile databases like BigTable, Dynamo, HBase, Cassandra, LevelDB, RocksDB, and AsterixDB, to name a few.&lt;/p&gt;

&lt;p&gt;Designed for write-intensive workloads, an LSM-tree is essentially made up of two segments: an in-memory component and an on-disk component. The in-memory part gets updated with every operation, and data gets flushed to the on-disk component once certain conditions are met.&lt;/p&gt;

&lt;p&gt;In this post, we'll walk you through the evolution of LSM-trees, discuss why they're all the rage, delve into their key components, explore common optimizations, and take a closer look at LevelDB's  implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  History of LSM-trees
&lt;/h2&gt;

&lt;p&gt;Discussing database systems often boils down to two primary data update strategies: in-place and out-of-place updates.&lt;/p&gt;

&lt;p&gt;In-place updates involve direct modifications to the data on disk, while out-of-place updates append new data values to a different disk location, leaving the original values unchanged.&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%2Fi.imgur.com%2FmX1S1jj.jpg" 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%2Fi.imgur.com%2FmX1S1jj.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above diagram, you'll notice how updating the value of key k1 from v1 to v4 works differently depending on the update strategy employed. When updating the value of key &lt;code&gt;k1&lt;/code&gt; from &lt;code&gt;v1&lt;/code&gt; to &lt;code&gt;v4&lt;/code&gt;, the in-place update updates the value directly, while the out-of-place create a new key-value pair and store the &lt;code&gt;(k1,v4)&lt;/code&gt; there.&lt;/p&gt;

&lt;p&gt;LSM-tree takes the out-of-place strategy and is designed to be write-optimized. With such context, you can understand the rise of LSM-trees, which is influenced by three key trends:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Modern applications are storing increasingly more data, which is further fueled by the decreasing price of storage and memory.&lt;/li&gt;
&lt;li&gt;Hence more applications are performing more insertions than read queries in their business logics.&lt;/li&gt;
&lt;li&gt;The global trend move to cloud-based datat management further supports immutability-based systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yes, the fact of "more write operation than read" on modern data store systems is the root cause why LSM-tree is so perferred nowadays.&lt;/p&gt;

&lt;p&gt;The concept of LSM-trees was introduced in 1996 by O'Neil and later popularized by Google's groundbreaking BigTable paper in 2006. Since then, a multitude of SQL and NoSQL databases have integrated LSM-trees, sparking active research in this field.&lt;/p&gt;

&lt;p&gt;The LSM-tree model was first introduced by O'Neil in his 1996 research paper titled "The Log-Structured Merge-Tree (LSM-Tree)." A decade later, in 2006, Google released a pivotal paper on Bigtable, which had a profound impact on the database and big data communities. Bigtable employs LSM-trees to manage the tablets that store the actual data. Since then, LSM-trees have gained widespread adoption as the storage layer in numerous NoSQL and even some SQL databases. Research into LSM-trees continues to be an active area of study.&lt;/p&gt;

&lt;h2&gt;
  
  
  Today's LSM-trees
&lt;/h2&gt;

&lt;p&gt;Today's LSM-trees generally consist of two main components: MemTable and SSTable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: While not all LSM-trees are built with MemTables and SSTables, these components are the most commonly used. This section outlines a typical LSM-tree architecture, using LevelDB as an illustrative example. Each data storage system may have its own unique implementation, but the core concepts remain consistent.&lt;/p&gt;
&lt;/blockquote&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%2Fi.imgur.com%2FDeo5BUP.jpg" 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%2Fi.imgur.com%2FDeo5BUP.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the LSM-tree structure, the MemTable serves as a temporary in-memory buffer for incoming write operations. This write buffer stores data in RAM, allowing for quick writes. When the MemTable fills up or a specific trigger occurs, its data is sorted and written to disk as an SSTable (Sorted String Table). This batch processing minimizes disk I/O and is particularly advantageous in write-heavy applications. After flushing, a new MemTable is created to host the newly incomming requests.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generally, there's only one active MemTable in the system at any given time, as depicted in the figure below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SSTables are immutable files containing a sequence of sorted key-value pairs. They offer several features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key Ordering&lt;/strong&gt;: Keys are sorted, facilitating efficient range queries and ordered data retrieval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indexed&lt;/strong&gt;: An index often accompanies an SSTable, enabling fast key lookups by pointing to specific data positions within the file.&lt;/li&gt;
&lt;/ul&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%2Fi.imgur.com%2FpsL38FX.jpg" 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%2Fi.imgur.com%2FpsL38FX.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SSTables are grouped into "levels" on disk. A higher level usually contains more SSTables than the one below it. When a MemTable is flushed to disk, it creates a new SSTable at level 0. Multiple SSTables can exist at this level, and their key ranges may overlap, as shown above.&lt;/p&gt;

&lt;p&gt;A compaction is triggered when the number of SSTables in a level reaches a certain threshold. In such a case, an SSTable from &lt;em&gt;level L&lt;/em&gt; is chosen, along with any overlapping SSTables from &lt;em&gt;level L+1&lt;/em&gt;. These are merged to form new SSTables at &lt;em&gt;level L+1&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compactions are performed in the background, ensuring that read and write operations aren't interrupted.&lt;/p&gt;
&lt;/blockquote&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%2Fi.imgur.com%2F5bPx2kK.jpg" 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%2Fi.imgur.com%2F5bPx2kK.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, if an SSTable in &lt;em&gt;level L&lt;/em&gt; has a key range of 101-150, any SSTables in &lt;em&gt;level L+1&lt;/em&gt; with overlapping key ranges would also be selected for merging, whose key ranges are &lt;code&gt;31-120&lt;/code&gt; and &lt;code&gt;121-150&lt;/code&gt;.&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%2Fi.imgur.com%2FOGmegbq.jpg" 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%2Fi.imgur.com%2FOGmegbq.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New SSTables are generated at &lt;em&gt;level L+1&lt;/em&gt;, based on the merge result of the 3 selected SSTables. The count of the newly generated SSTables depends not only on key ranges but also on the data size for each key. The primary goal is to maintain uniform SSTable sizes. Therefore, after compaction, the SSTable at &lt;em&gt;level L&lt;/em&gt; was removed, and its data is now merged in &lt;em&gt;level L+1&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As you can see, except for level 0, &lt;strong&gt;SSTables at each level have non-overlapping key ranges&lt;/strong&gt;. This design allows for efficient point or range queries, as each key can be located without scanning multiple SSTables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization on LSM-trees
&lt;/h2&gt;

&lt;p&gt;While each storage system may have its unique optimizations, several common techniques are often employed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bloom Filters&lt;/strong&gt;: Used to minimize disk reads by quickly determining if a key exists in a certain level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compaction Strategies&lt;/strong&gt;: Tailored to reduce write amplification and read latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partitioning&lt;/strong&gt;: Enhances concurrency and reduces contention by dividing data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching&lt;/strong&gt;: Strategies are in place to limit disk access and boost performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indexing&lt;/strong&gt;: Auxiliary structures are employed to speed up lookups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression&lt;/strong&gt;: Saves space and improves I/O efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuning Size Ratios&lt;/strong&gt;: Balances read and write performance by adjusting the size ratios between levels.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In today's data-rich environment, LSM-trees serve as a sturdy foundation for modern storage systems. Understanding LSM-trees is more than just a primer; it's essential for grasping how contemporary data storage operates. Through this blog, my aim is to equip you with the fundamentals of LSM-trees, so you'll have a clearer understanding the next time you encounter them.&lt;/p&gt;

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

&lt;p&gt;[1] Chen Luo and Michael J. Carey. 2020. &lt;strong&gt;LSM-based Storage Techniques: A Survey.&lt;/strong&gt;The VLDB Journal 29, 1 (January 2020), 393–418. DOI:&lt;a href="https://doi.org/10.1007/s00778-019-00555-y" rel="noopener noreferrer"&gt;https://doi.org/10.1007/s00778-019-00555-y&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] Patrick O’Neil, Edward Cheng, Dieter Gawlick, and Elizabeth O’Neil. 1996. &lt;strong&gt;The log-structured merge-tree (LSM-tree)&lt;/strong&gt;. Acta Informatica 33, 4 (June 1996), 351–385. DOI:&lt;a href="https://doi.org/10.1007/s002360050048" rel="noopener noreferrer"&gt;https://doi.org/10.1007/s002360050048&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] Subhadeep Sarkar and Manos Athanassoulis. 2022. &lt;strong&gt;Dissecting, Designing, and Optimizing LSM-based Data Stores.&lt;/strong&gt; In Proceedings of the 2022 International Conference on Management of Data, ACM, Philadelphia PA USA, 2489–2497. DOI:&lt;a href="https://doi.org/10.1145/3514221.3522563" rel="noopener noreferrer"&gt;https://doi.org/10.1145/3514221.3522563&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4] leveldb/doc/impl.md at main · &lt;strong&gt;google/leveldb&lt;/strong&gt;. GitHub. Retrieved October 21, 2023 from &lt;a href="https://github.com/google/leveldb/blob/main/doc/impl.md" rel="noopener noreferrer"&gt;https://github.com/google/leveldb/blob/main/doc/impl.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>lsmtree</category>
      <category>database</category>
      <category>datastructures</category>
    </item>
  </channel>
</rss>
