High-performance scalable hash index based on hybrid storage
By building a three-layer index structure of hybrid storage on persistent memory devices and optimizing hash indexes using CPU cache and volatile memory, the traffic and write amplification problems in existing technologies are solved, and high-performance and high-concurrency hash index operations are achieved.
Patent Information
- Application Number
- CN202311023921.5
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2023-08-15
- Publication Date
- 2025-09-05
- Estimated Expiration
- 2043-08-15
AI Technical Summary
Existing hash index designs do not fully utilize the hardware characteristics of persistent memory devices, resulting in traffic and write amplification, affecting system performance.
A three-layer index structure based on hybrid storage is adopted, which utilizes CPU cache and volatile memory to optimize the insertion and search operations of hash indexes through log-based searchless insertion, bottom-up search and low-overhead split checking.
Effectively reduce persistent memory traffic amplification, improve system performance and concurrency, and enhance write efficiency and search speed.
Smart Images

Figure CN117112557B_ABST
Abstract
Description
Technical Field
[0001] The present invention relates to the technical field of key-value storage and hash indexing, and in particular to a high-performance scalable hash index construction method based on hybrid storage for a persistent memory device with a persistent CPU cache. Background Art
[0002] Hash indexes, also known as hash indexes, are widely used as a cornerstone of data-intensive applications such as in-memory databases and key-value stores due to their constant lookup time complexity, ensuring fast response times. For any given keyword, a hash index determines the location where key-value pairs are stored based on the keyword's mapping through a hash function. When a search request is made, the hash index substitutes the keyword into the hash function and obtains the address of the record containing the keyword in the table. The value corresponding to the keyword can then be accessed using this address.
[0003] The emergence of new persistent memory storage devices presents new opportunities for key-value storage system design. With the rapid development of related electronic circuit technologies, persistent memory implementations, such as phase-change memory, resistive random access memory, and magnetoresistive memory, have emerged. Intel's Optane persistent memory has also become commercially available. Persistent memory offers low latency, non-volatility, and byte-addressability, along with advantages such as high scalability, low energy consumption, and high storage density. Depending on the implementation technology, persistent memory devices have varying access granularity and persistence domains, along with differentiated hardware features. For example, both the Intel Optane persistent memory 100 series and 200 series devices have 256-byte access granularity (the smallest unit of read and write), but utilize different persistence domains (storage areas that ensure data is not lost in the event of a power outage or system crash). The 100 series' persistence domain consists solely of the memory controller and persistent memory (standard persistence domain), while the 200 series includes the CPU cache (enhanced persistence domain). Existing research results can be divided into three categories: (1) Write-optimized hash indexes for persistent memory with high write overhead (Pengfei Zuo and Yu Hua. A Write-Friendly and Cache-Optimized Hashing Scheme for Non-Volatile Memory Systems. IEEE Transactions on Parallel and Distributed Systems, 29(5): 985–998, 2017; Pengfei Zuo, Yu Hua, and Jie Wu. Write-Optimized and HighPerformance Hashing Index Scheme for Persistent Memory. In 13th USENIX Symposium on Operating Systems Design and Implementation (OSDI 18), pages 461–476, 2018.); (2) Hash indexes optimized for the high full-table rehashing overhead of hash indexes (Baotong Lu, Xiangpeng Hao, Tianzheng Wang, and Eric Lo. Dash: Scalable Hashing on Persistent Memory.Proceedings of the VLDB Endowment, pages 1147–1161, 2020; Moohyeon Nam, Hokeun Cha, Young-ri Choi, Sam HNoh, and Beomseok Nam. Write-Optimized Dynamic Hashing for PersistentMemory. In 17th USENIX Conference on File and Storage Technologies (FAST 19), pages 31–44, 2019; Pengfei Zuo, Yu Hua, and Jie Wu. Write-Optimized and HighPerformance Hashing Index Scheme for Persistent Memory. In 13th USENIX Symposium on Operating Systems Design and Implementation (OSDI 18), pages 461–476, 2018.); (3) Reducing the high concurrency control overhead caused by persistent memory locks through lock-free design (Zhangyu Chen, Yu Hua, Bo Ding, and Pengfei Zuo. Lock-Free Concurrent Level Hashing forPersistent Memory.In 2020USENIX Annual Technical Conference(USENIX ATC 20),pages 799–812,2020;Se Kwon Lee,Jayashree Mohan,Sanidhya Kashyap,Taesoo Kim,and Vijay Chidambaram.Recipe:Converting Concurrent DRAM Indexes toPersistent-Memory Indexes.In Proceedings of the 27th ACM Symposium onOperating Systems Principles, pages 462–477, 2019; Yoav Zuriel, Michal Friedman, Gali Sheffi, Nachshon Cohen, and Erez Petrank.Efficient Lock-Free DurableSets. Proceedings of the ACM on Programming Languages, 3(OOPSLA):1–26, 2019.). It is observed that existing research results consider the general characteristics of persistent memory such as high performance, low latency, and high write overhead when designing key-value storage systems, but ignore the hardware characteristics of persistent memory device access granularity and persistent memory bandwidth limitations. Ignoring the first two makes the non-volatile memory suffer from large traffic amplification. There are two reasons for the traffic amplification: (1) Existing research results often need to ensure the uniqueness of the key by searching before insertion, and use linear probing to search for the location where the key value may exist, so that no matter whether it is inserted or searched, many useless negative searches are generated due to linear probing; (2) Existing research results use special CPU instructions to bypass the CPU cache. Since the persistent memory access granularity is 256B, each time a key-value pair is written, 256B of data needs to be written to the persistent memory, resulting in large write amplification. Therefore, how to design hash indexes based on persistent memory with block-like access granularity to fully utilize its hardware characteristics remains a challenging and important problem in the field of hash indexing. Summary of the Invention
[0004] The purpose of the present invention is to address the above-mentioned problems existing in the prior art, utilize the persistence characteristics of the CPU cache, and provide a high-performance, low-latency, persistent CPU cache and volatile memory to improve performance by reducing the traffic amplification of the persistent memory. A high-performance scalable hash index construction method based on hybrid storage is provided, which utilizes the persistence characteristics of the CPU cache to improve performance by reducing the traffic amplification of the persistent memory. A memory table pool is established on the bottom cache of the persistent CPU cache, and the number of memory tables can be flexibly adjusted according to the write load to reduce system resource competition; the update operation of the memory table index structure is delayed, and asynchronous batch updates are performed by background threads to reduce the software overhead on the system write critical path; a data write back mechanism based on memory tables is used to write the memory tables from the CPU cache back to the persistent memory to improve the write efficiency of the persistent memory device; multiple memory tables written back to the persistent memory may contain old or invalid data, which affects the search performance. The memory table index merging mechanism merges the index structures of multiple memory tables, eliminates invalid index nodes, and improves the system search efficiency.
[0005] The present invention comprises the following steps:
[0006] Step 1: Based on the three-layer structure of CPU cache, volatile memory, and persistent memory, the specific steps include:
[0007] 1.1 Create a scalable hash index on persistent memory with a large bucket size.
[0008] 1.2 Create a collection log pool in persistent memory. Each log is 256 bytes in size, containing 15 key-value pairs and 16 bytes of metadata. By frequently accessing the log pool and not explicitly evicting logs, the logs are kept in the CPU cache. The location where the collection log is written is determined based on the first K bits of the hash value.
[0009] 1.3 Create a scalable index on volatile memory with the same structure as persistent memory, with each bucket set to a smaller size;
[0010] 1.4 Create a backup log in persistent memory to ensure the recovery of volatile memory scalable indexes;
[0011] 1.5 Create a feature array and bitmap in volatile memory, where each element is a key in the corresponding index in persistent memory, and the element value is 2 bytes of the corresponding key; the bitmap is used to manage the space in the memo log.
[0012] Step 2: Log insertion without search. The specific steps include:
[0013] 2.1 Determine the write location by hashing the value, and use the Request and Exchange (CAS) primitive to increment the number of items in the log and determine the write location.
[0014] 2.2 Write to the log in the order of value first and key later at the corresponding position;
[0015] 2.3 After writing is completed, the CAS primitive is used to set the bitmap in the log to 1 to indicate that the writing is completed;
[0016] 2.4 When the number of log key-value pairs in the cache reaches the set threshold, the log is copied to the backup log using the memory copy instruction, and the key values in the log are inserted into the volatile index respectively.
[0017] 2.5 When the number of key-value pairs in a bucket in the volatile index reaches the set threshold, the bucket will be copied to the non-volatile index using the memory copy instruction.
[0018] Step 3: Bottom-up search, the specific steps include:
[0019] 3.1 Take out 2 bytes of the hash value of the key to be searched and compare it with the feature array in the volatile memory using SIMD technology. If they are the same, compare the key with the key in the corresponding non-volatile index; if they are the same after comparison, take out the corresponding value;
[0020] 3.2 When the search key does not exist in the eigenvalue array, compare the corresponding buckets of the volatile index, and if they are the same, take out the value;
[0021] 3.3 When the volatile index does not have a value, compare the key-value pairs in the corresponding cache log. If they are the same, take them out. If there is no identical key after the search, it is considered that the key does not exist in the index.
[0022] Step 4: Low-overhead split check. The specific steps include:
[0023] 4.1 When the number of key-value pairs in a bucket within the volatile index reaches the set threshold, the local depth of the segment is compared with the global depth of the directory. If they are the same, the directory size is doubled, the depth is increased by one, and the comparison is repeated. If they are different, two new segments are created and the pointers are stored in the new segment pointer within the old segment to avoid permanent loss of the new segment location due to power outage during the split.
[0024] 4.2 After the allocation is complete, the segment is split and the key-value pairs in the bucket are read out one by one. The hash value determines which new segment they belong to. After the new segment is determined, the corresponding bucket in the new segment is searched for duplicate keys. If there are duplicate keys, the key-value pair is inserted repeatedly and the data is not moved to the new segment. If not, the data is moved to the new segment.
[0025] Compared with the prior art, the present invention has the following outstanding advantages:
[0026] 1. The present invention organizes and collects log pools on a high-performance, low-latency persistent CPU cache, bridging the gap between the key-value pair size and the write granularity of persistent memory.
[0027] 2. The present invention adopts a lock-free design in collecting logs, fully utilizing the speed advantage of the cache and improving the system concurrency performance.
[0028] 3. The present invention completely removes the search before insertion, and through bottom-up search and split consistency check, ensures the correctness of the hash index while reducing the read-write mix during insertion, thereby improving the index insertion performance.
[0029] 4. The present invention adopts characteristic array and SIMD technology, which can effectively improve the search operation speed.
[0030] 5. The three-layer index structure based on hybrid storage proposed in the present invention increases the granularity of data written back to persistent memory from the size of key-value pairs to the size of persistent memory granularity, thereby improving the write bandwidth utilization efficiency of persistent memory. BRIEF DESCRIPTION OF THE DRAWINGS
[0031] Figure 1 This diagram shows an example of a three-tier structure based on hybrid storage.
[0032] Figure 2 This diagram shows an example of the process of flushing the log to the volatile memory index and backing up the log when the collection log write threshold is triggered.
[0033] Figure 3This diagram shows an example of the process of flushing indexes and special arrays to persistent memory when a volatile index write threshold is triggered.
[0034] Figure 4 The experimental results of single-thread write, positive and negative search, and deletion performance of the system under balanced and tilted loads are shown in the figure.
[0035] Figure 5 The experimental results of the system's multi-threaded writing, positive and negative search, and deletion performance under balanced load are shown in the figure.
[0036] Figure 6 The experimental results of the system's multi-threaded write, positive and negative search, and deletion performance under tilted load are shown in the figure.
[0037] Figure 7 The following is the experimental result of the system performance test under different real loads.
[0038] Figure 8 The experimental results of system load factor under different insertion key-value pairs are shown in the figure.
[0039] Figure 9 This is the experimental result diagram of the system under different persistence domains.
[0040] Figure 10 This is the experimental result graph of system recovery time under the number of inserted key-value pairs.
[0041] Figure 11 Experimental results of system performance test for different collection log sizes.
[0042] Figure 12 The experimental results of system performance test with different bucket sizes are shown in the figure.
[0043] Figure 13 The following is the experimental result of system performance test under a single Optane 200 memory. DETAILED DESCRIPTION
[0044] The following embodiments will further illustrate the present invention with reference to the accompanying drawings. It should be understood that the specific embodiments described herein are only used to explain the present invention and are not intended to limit the present invention.
[0045] The present invention aims to improve the performance of persistent memory by utilizing high-performance, low-latency CPU cache and volatile memory to reduce traffic amplification. The hash index system consists of four components: a three-tiered structure based on hybrid storage, log-based searchless insertion, bottom-up search, and low-overhead split checking. The main idea of the system is to use persistent CPU cache and volatile memory as auxiliary storage for non-volatile memory, adding them to the storage stack and establishing corresponding data structures on top of them to reduce and absorb accesses to non-volatile memory. Log-based searchless insertion is also proposed. By removing the search during insertion and establishing a log in the cache to collect key-value pairs, it completely eliminates search amplification caused by insertion and reduces write amplification caused by mismatches between key-value pairs and accesses. A top-up search is then used to ensure search correctness and offload most persistent memory accesses to volatile memory during access. A low-overhead split checking is added during splitting to selectively move old segment data by retrieving key-value pairs in the new segment, resolving the problem of duplicate keys caused by searchless insertion.
[0046] The core of the embodiment of the present invention is to build a high-concurrency hash index based on hybrid storage. The specific implementation includes the following steps:
[0047] 1) Based on the three-layer structure of CPU cache, volatile memory and persistent memory:
[0048] (1.1) Initialize an extensible hash index (persistent index) in persistent memory. The index consists of directories, segments, and buckets. The index contains a directory, where each entry in a directory is a persistent pointer to a segment. A segment is a collection of buckets, each of which can hold 256 16B key-value pairs. Each segment stores key-value pairs with the same hash value for the first M bits, and each bucket within the segment stores key-value pairs with the same hash value for the last N bits. An allocation function is used to allocate memory for the index's directories and segments in persistent memory, and the segment pointers are stored in the directories.
[0049] (1.2) A log pool is initialized in persistent memory through an allocation function. The log pool consists of multiple collection logs, each of which stores key-value pairs with the same hash value for the first K bits (K is not necessarily equal to M). Each log is 256B in size and can store 15 16B key-value pairs and 16B of metadata to completely eliminate write amplification caused by the granularity of persistent memory. When the log is full, the data is copied from the collection log to the backup log using memory replication. Since each write requires appending the key-value pair to the log, frequent access to the log pool and no explicit eviction of the log causes the log to reside in the CPU cache.
[0050] (1.3) An extensible hash index (volatile index) is initialized in volatile memory through an allocation function. This index has the same structure as the persistent index, with directories, segments, and buckets. The directory and segment sizes are the same as those of the hash index in persistent memory, but the buckets are only 256 bytes, accommodating 16 16-byte key-value pairs.
[0051] (1.4) Create a backup log in persistent memory. The data stored in the backup log is identical to the volatile index data, but the data in the backup log is unordered. This ensures that the volatile memory index can be restored after a power outage. The backup log structure is a pointer array, with each array element pointing to a backup log pool. If the backup log pool is insufficient, a log pool of twice the size is requested, and the pointer to the pool is placed in the pointer array.
[0052] (1.5) Create a feature array and bitmap in volatile memory. The feature array is a three-dimensional array, with the three dimensions representing the location within the directory, the location within the segment, and the location within the bucket. Each element in the feature array is 2 bytes in size, and its value represents a portion of the key in the corresponding index in persistent memory. The bitmap is used to manage the space in the memo log. Because the backup log is unordered, when the collection log is flushed to the backup log, the bitmap at the corresponding position is set to 1. When the data in the bucket of the volatile index is flushed to the persistent index, the bitmap of the corresponding data is set to 0.
[0053] 2) Logging without search insertion:
[0054] (2.1) For an insert request, the first K bits of the hash value are used to determine the write location in the log. The CAS primitive is used to increment the variable for the number of items in the log by one to determine the write location of the key-value pair.
[0055] (2.2) The system writes the value directly to the specified empty slot, and then writes the key to the empty slot after the value is written. This method of writing the value first and then the key ensures that other threads will not return incorrect results after searching for the key because the value has not been written yet.
[0056] (2.3) After the key-value pair is written, the system uses the CAS primitive to set the corresponding position of the bitmap in the collection log to 1. After setting it to 1, it indicates that the write is complete and can be flushed to the backup log.
[0057] (2.4) When the number of log key-value pairs in the cache reaches a set threshold, the thread currently operating on the log will use the CAS primitive to swap its own shadow log with the log it is operating on, to prevent subsequent flushes from blocking other threads from inserting into the log. A memory copy instruction is used to copy the collection log to be flushed to the backup log, and the corresponding position in the bitmap is set to 1, indicating that the backup log space is occupied. The key values in the collection log are then inserted into the volatile index.
[0058] (2.5) When the number of key-value pairs in a bucket in the volatile index reaches the set threshold, the system will use the memory copy instruction to append the full bucket to the same bucket in the same directory of the persistent index, increase the number of key-value pairs in the persistent index bucket by 16 (the size of the volatile index bucket), and set the corresponding position in the bitmap to 0, indicating that the corresponding position in the backup log has been released.
[0059] 3) Bottom-up search:
[0060] (3.1) For search operations, the searched segment and bucket are determined by the hash value of the search key. Two bytes of the search key's hash value are retrieved and compared with the feature array in volatile memory. Single Instruction Multiple Data (SIMD) technology further accelerates the feature array comparison process. If the key matches, the key in the corresponding non-volatile index is retrieved and compared with the searched key. If the comparison results in a match, the corresponding value in the index is returned.
[0061] (3.2) When the search key cannot be found in the persistent index after comparing the feature array, the system finds the corresponding bucket on the volatile index and compares the keys one by one from small to large to see if they are equal. If they are equal, the value is taken out and returned.
[0062] (3.3) When the volatile index cannot find the key to be searched, the system obtains the number of existing key-value pairs in the corresponding collection log, compares the key with the key to be searched one by one, and takes them out if they are equal. If there is no identical key after the search, it is considered that the key does not exist in the index.
[0063] 4) Low-overhead split checking:
[0064] (4.1) When the number of key-value pairs in a bucket within the volatile index reaches a set threshold, the local depth of the segment is compared with the global depth of the directory. If they are the same, the directory size is doubled, the depth is increased by one, and the comparison is repeated. If they are different, two new segments are created, and the pointers to the new segments are stored in the new segment pointer within the old segment to prevent the new segment location from being permanently lost due to power outage during the split.
[0065] (4.2) After allocation, the segment is split. The key-value pairs in the bucket are read out one by one, and the new segment is determined based on the hash value. After the new segment is determined, the corresponding bucket in the new segment is searched for duplicate keys. If duplicate keys are found, the key-value pair is inserted repeatedly, and the data is not moved to the new segment. If not, the data is moved to the new segment.
[0066] The core of this embodiment is to implement high-performance and high-concurrency hash indexing on a persistent memory device equipped with a persistent CPU cache and volatile memory. The specific implementation mainly consists of the following modules:
[0067] 1. Collection log pool module based on persistent CPU cache: This module is built in persistent memory and stores the collection log pool at the bottom level of the persistent CPU cache through frequent reads and no explicit eviction. The collection log pool contains multiple collection logs of equal size. Each collection log table stores 15 16-byte key-value pairs and 16-byte metadata for concurrency control. The write position of the collection log is determined by the first K bits of the key's hash value. Each collection log is divided into five parts: (1) key-value pair storage space, used to store the key-value pair data stored in the collection log (2) version number and completion bitmap. Before the log is flushed, this position is used as the completion bitmap. When the write is completed, the corresponding bitmap is set to 1, indicating the completion of the corresponding write operation. When the collection log is full, this position is used as the unique global version number of each log, recording the relative time of the data when flushing, used for data recovery during power outages, and occupies 64 bits. (3) is_flush flag indicates whether the log is being flushed, occupying 1 bit. (4) counter records the number of occupied key-value pair slots, used for concurrency control, occupying 4 bits. (5) the location of the backup log, which is determined when the collection log is initialized and occupies 54 bits. When writing a key-value pair, first use the atomic primitive operation to increase the counter by one, indicating that the slot is occupied. After the key-value pair is inserted, use the atomic primitive operation to set the corresponding position of the completion bitmap to 1, indicating that the write has been completed.
[0068] 2. Volatile index module: This module is responsible for reclassifying the data in the collection log and writing it to the persistent index. When the collection log is full, it will be written to the backup log and the corresponding bitmap will be set to 1. At the same time, each key-value pair in the collection log will be written to the corresponding bucket of the persistent index to ensure the correctness of the search. This module mainly consists of three parts: (1) Volatile hash index on volatile memory, which is used to classify key-value pairs with the same first K bits in the collection log into corresponding buckets according to the standard of first M bits and last N bits. After waiting for 16 key-value pairs (256B), the data will be written to the persistent index. (2) Backup log on persistent memory, which stores the collection log written to the volatile hash index and is used to restore the hash index on volatile memory after power failure. (3) Bitmap on volatile memory, which is used to manage the backup log on persistent memory. When a key-value pair is written to the backup log, the corresponding bitmap will be set to 1 at the same time; when the bucket on the volatile index is written to the persistent index, the corresponding bitmap of the backup log will also be set to 0. Figure 2 Given the process of flushing the collected log to the volatile index, the log size is 4, and 11, 19, 31, and 65 are written to different buckets of the volatile index respectively, and the positions in the bitmap are set to 1.
[0069] 3. Persistent Index Module: This module is responsible for storing most key-value pairs and providing fast lookups for the key-value pairs stored there. This module mainly consists of two parts: (1) a persistent in-memory hash index responsible for storing key-value pairs. In the specific implementation, an extensible hash index based on directory, segment, and bucket layers is used; (2) a feature array in volatile memory that stores a portion of the key value and is used to filter negative searches to improve query efficiency. Figure 3 A schematic diagram of flushing the last bucket in segment 3 of the volatile index to the persistent index is given. First, the data is flushed to the bucket in segment 3 of the persistent index through memory copying. After the copy is completed, the characteristic value of each key is written to the characteristic array, and the corresponding position in the bitmap is set to 0, indicating that the corresponding data in the backup log has been released.
[0070] The system structure prototype implemented by the present invention is as follows Figure 1 As shown in the figure, it includes a collection log pool module based on persistent CPU cache, a volatile index module, and a persistent index module. The collection log module based on persistent CPU cache consolidates small key-value pairs into 256B data blocks that conform to the Optane granularity for writing. The volatile index module is responsible for further reclassifying the consolidated data blocks in volatile memory and writing them to the persistent index. The persistent index module stores a large amount of key-value pair data and provides high-speed query for the persistent index through the feature array.
[0071] The performance test of the present invention is given below:
[0072] The prototype system of the present invention is deployed on a single server equipped with two Intel Xeon 5318Y processors, each with 128GB of memory. Four 128GB Intel Optane 200 series persistent memory devices are configured on one of the processors. It uses the Interleaved AppDirect Mode with 4KB granularity for cross-access and runs the Ubuntu 20.04 operating system. All tests are limited to running on the processor equipped with persistent memory and its local memory. The experimental key of the key-value pair is set to 16 bytes, and all data is stored in the persistent memory during testing. The test system includes: (1) CCEH, which introduces the concept of segments based on scalable hashing to reduce directory size; (2) DASH, which delays splits to improve throughput by balanced insertion, overflow buckets, etc.; (3) Level, a two-layer write-optimized scalable hash index with only the top layer being addressable; (4) CLevel, a completely lock-free version of Level, which improves its concurrency; and (5) ElimDA, a high-concurrency hash index on hybrid storage, i.e., the present invention. If the number of key-value pairs is not specified, the default number of key-value pairs for each test operation is 50 million. The key size of the key-value pair is 8 bytes. The test is repeated 5 times, and the average value is taken as the test result. Tests 1 and 4 both use a single-user thread configuration.
[0073] 1. System single-thread general performance test:
[0074] The single-threaded general performance test uses the YCSB tool to generate loads for write, positive search, negative search, and delete operations. The test evaluates the system throughput of the present invention and other comparison systems under balanced and skewed data distribution, performing four operation scenarios. The test results are as follows: Figure 4 The left figure shows the throughput under balanced load, and the right figure shows the throughput under skewed load. Across the four operation scenarios, ElimDA achieves average performance improvements of 489.4%, 80.9%, 247.9%, and 68.8% compared to CCEH, DASH, Level, and Clevel. ElimDA achieves even greater improvements in writes and negative searches. This is due to the optimized writes of the three-layer structure and the accelerated reads of the feature array, which enable ElimDA to perform better in both operations.
[0075] 2. System scalability performance test:
[0076] The scalability performance test uses YCSB to generate loads for write, positive search, negative search, and delete operations. The test evaluates the system throughput of the present invention and other comparison systems in executing four operation scenarios under different threads under balanced and skewed data distribution. The test results are as follows: Figure 5 and 6 shown. Figure 5 represents the throughput under balanced load, Figure 6 Represents the throughput under skewed loads. As the number of thread indexes increases, all hash indexes achieve higher throughput. Furthermore, compared to CCEH, DASH, Level, and Clevel, ElimDA achieves an average throughput improvement of up to 635.7%.
[0077] 3. Real load simulation performance test:
[0078] The real load simulation performance test uses the YCSB tool to simulate four real load scenarios with different configurations. Since DASH and Level do not support update operations, there are no results for the two in the test including updates. The test results are as follows Figure 7 In all scenarios, the throughput of ElimDA is 175.2%, 229.3%, 199.8%, and 199.3% higher than that of existing hash indexes on average.
[0079] 4. Load factor test:
[0080] The test configures the number of key-value pairs, up to 240 million key-value pairs, each key-value pair is 16B in size, and tests the load factor of the index under different key-value pairs in a single thread. The test results are as follows: Figure 8 As shown in the figure, ElimDA's load factor fluctuates between 48.0% and 87.6%, averaging 68.9%. This is better than CCEH, Clevel, and DASH, but slightly lower than Level (average 69.5%). This is because Level uses cuckoo hashing, which increases the load factor at the expense of read performance.
[0081] 5. System suitability test
[0082] The test modified the ElimDA code and provided a version of ElimDA under volatile CPU cache, named ElimDA. Its performance comparison with other indexes under different threads was tested. The test results are as follows Figure 9 As shown in the figure, ElimDA-ADR's throughput generally increases with the number of threads (from 2.4Mop / s to 6.1Mop / s). In addition, ElimDA-ADR still outperforms the other four hash indexes by 289.8% in average insertion throughput.
[0083] 6. System recovery performance test
[0084] Because bitmaps, hash indexes, and feature values are maintained in volatile memory, they must be rebuilt from backup logs in the event of a power outage. The test compared ElimDA's recovery time under different conditions by varying the number of threads recovered and the number of key-value pairs inserted. Figure 10Figure (a) in represents the time required to restore the volatile index structure and eigenvalues. Figure 10 Figure (b) shows the time required to restore data and bitmaps within volatile indexes. ElimDA can restore 50 million items in just 0.76 seconds, with optimal structure restoration achieved with four threads and data restoration with eight threads, achieving a throughput of 173.3 Mop / s.
[0085] 7. System sensitivity testing
[0086] The test measures the performance of ElimDA under different configuration parameters by modifying the number of collected logs, the size of volatile index buckets, and the size of persistent index buckets. The test results are as follows: Figure 11 , Figure 12 shown. Figure 11 This figure shows the insertion throughput performance of ElimDA under different threads when the number of collection logs increases from 1024 to 16,384. ElimDA's throughput generally increases with the number of collection logs, from 6.5 Mop / s (when there are 1,024 collection logs) to 7.4 Mop / s (when there are 16,384 collection logs). Figure 12 Figure (a) increases the volatile index bucket size from 32B to 512B. It can be seen that the insertion performance first increases with the increase of bucket size and stabilizes after 256B. This is because buckets before 256B will produce write amplification, and increasing the bucket size after 256B will no longer reduce write amplification. Figure 12 In Figure (b), increasing the persistent index bucket size from 1KB to 16KB, the forward search throughput decreases because ElimDA needs to probe more slots to find the requested item. Meanwhile, the insertion throughput increases with the increase in the persistent index bucket size because larger persistent index buckets can reduce the number of splits, thereby improving insertion performance.
[0087] 8. System performance test with limited bandwidth under single Optane:
[0088] The test configurations were different for the amount of Optane memory. The hash index was tested for the throughput of four operations: insert, positive search, negative search, and delete under a single Optane memory. The number of threads was 24. The test results are as follows: Figure 13 As shown. Figure 13 It can be seen that although the Optane bandwidth is limited under a single Optane root, ElimDA still increases the throughput of different operations by an average of 0.75×-34.7×, and its performance is better than that of its competitors.
[0089] The present invention establishes a resizable collection log pool at the bottom level of a persistent CPU cache and writes it to persistent memory in log units, bridging the gap between key-value pair size and the write granularity of persistent memory. A smaller index is established in volatile memory to categorize the key-value pairs flushed to the collection log. Searchless insertion and bottom-up search are employed to eliminate pre-insert searches while ensuring correctness, reducing the read-write mix of insert operations. Checkless insertion results in multiple insertions of duplicate key values, reducing the load factor and increasing the number of splits. Low-overhead consistency checks are added to the splits to eliminate the index space occupied by duplicate keys. Searching large hash buckets increases the average number of probes, impacting search performance. The index key's feature values are stored in volatile memory, and SIMD technology is employed to absorb unused bucket probes in volatile memory, improving index search efficiency. Experiments demonstrate that the present invention, based on hybrid storage with persistent memory, provides a highly concurrent and high-performance hash index. Existing hash-based indexing methods fail to account for the access granularity of persistent memory devices and the limited bandwidth of persistent memory. This leads to significant traffic amplification due to pre-insert searches and direct writes bypassing the CPU cache. This invention integrates the CPU cache and volatile memory into the storage stack, organizing the collection log pool and volatile index on top of it, and optimizing the index read and write processes.
[0090] The above embodiments are only preferred embodiments of the present invention and should not be considered to limit the scope of the present invention. All equivalent changes and improvements made within the scope of the present invention should still fall within the scope of the present invention.
Claims
1. High-performance scalable hash index based on hybrid storage, characterized by The following steps are involved: Step 1: A three-layer structure based on CPU cache, volatile memory, and persistent memory, including: 1.1 Create a scalable hash index on persistent memory with a large bucket size. 1.2 Create a collection log pool in persistent memory. Each log is 256 bytes in size, containing 15 key-value pairs and 16 bytes of metadata. By frequently accessing the log pool and not explicitly evicting logs, the logs are kept in the CPU cache. The location where the collection logs are written is determined based on the first K bits of the hash value. 1.3 Create a scalable index on volatile memory with the same structure as persistent memory, with each bucket set to a smaller size; 1.4 Create a backup log in persistent memory to ensure the recovery of volatile memory scalable indexes; 1.5 Create a feature array and bitmap in volatile memory, where each element is a key in the corresponding index in persistent memory, and the element value is 2 bytes of the corresponding key; the bitmap is used to manage the space in the memo log; Step 2: Logged searchless insertion, including: 2.1 Determine the write location by hashing the value and using the request and exchange CAS primitive to increment the number of items in the log and determine the write location. 2.2 Write to the log in the order of value first and key at the corresponding position; 2.3 After writing is completed, the CAS primitive is used to set the bitmap in the log to 1 to indicate that the writing is completed; 2.4 When the number of log key-value pairs in the cache reaches the set threshold, the log will be copied to the backup log using the memory copy instruction, and the key values in the log will be inserted into the volatile index respectively; 2.5 When the number of key-value pairs in a bucket in the volatile index reaches the set threshold, the bucket will be copied to the non-volatile index using the memory copy instruction; Step 3: Bottom-up search, including: 3.1 Take out 2 bytes of the hash value of the key to be searched and compare it with the feature array in the volatile memory using SIMD technology. If they are the same, compare the key with the key in the corresponding non-volatile index; if they are the same after comparison, take out the corresponding value; 3.2 When the search key does not exist in the eigenvalue array, compare the corresponding buckets of the volatile index, and if they are the same, take out the value; 3.3 When the volatile index does not have a value, compare the key-value pairs in the corresponding cache log. If they are the same, remove them. If no identical key is found after the search, the key is considered not to exist in the index. Step 4: Low-overhead split checking, including: 4.1 When the number of key-value pairs in a bucket within the volatile index reaches the set threshold, the local depth of the segment is compared with the global depth of the directory. If they are the same, the directory size is doubled, the depth is increased by one, and the comparison is repeated. If they are different, two new segments are created and the pointers are stored in the new segment pointer within the old segment to avoid permanent loss of the new segment location due to power outage during the split. 4.2 After the allocation is completed, the segment is split and the key-value pairs in the bucket are read out one by one. The hash value determines which new segment the data belongs to. After the new segment is determined, the corresponding bucket in the new segment is searched for duplicate keys. If so, it means that the key-value pair is a duplicate inserted key-value pair and the data is not migrated to the new segment. If not, the data is migrated to the new segment.
2. The high-performance scalable hash index based on hybrid storage as claimed in claim 1, characterized in that In step 1.1, an extensible hash index is established on the persistent memory, and the size of each bucket is set to be relatively large. Specifically, the index consists of directories, segments, and buckets. The index contains a directory, and each item in a directory is a persistent pointer to a segment. A segment is a collection of multiple buckets, and a bucket contains 256 16B key-value pairs. Each segment stores key-value pairs with the same hash value for the first M bits, and each bucket in the segment stores key-value pairs with the same hash value for the last N bits. In the persistent memory, the allocation function is used to allocate memory to the directories and segments of the index in sequence, and the pointers in the segments are stored in the directories.
3. The high-performance scalable hash index based on hybrid storage as claimed in claim 1, characterized in that In step 1.3, an extensible index with the same structure as the persistent memory is established on the volatile memory, and the size of each bucket is set to be smaller. Specifically, the index has the same structure as the persistent index, and both have a directory, segment, and bucket structure. The directory and segment sizes are the same as the hash index directory and segment sizes of the persistent memory, but the bucket is only 256B and can accommodate 16 16B key-value pairs.
Citation Information
Patent Citations
Small write optimizing method for log file system based on nonvolatile memory
CN107784121A
Write optimization extensible Hash index structure based on nonvolatile memory and insertion, refreshing and deletion methods
CN113342706A