searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

LMDB基础介绍及使用

2023-06-26 01:17:45
878
0

引言

本人有幸在此前项目中使用LMDB为用户态存储提供高速数据库:原项目为了保证内核clean及方便日后内核升级兼容性,需要将内核态的私有实现全部移植到用户态。为了保证原有内核数据的读取效率不损失,经研究引入LMDB内存映射的方式作为用户态的替代方案存储内核数据得以解决。

引言部分将介绍LMDB数据库的背景和概述,为读者提供对LMDB的基本了解。

LMDB(Lightning Memory-Mapped Database)是一个轻量级、高性能、低内存占用和可靠性的键值存储数据库。它由Symas Corporation开发,最初是为了满足OpenLDAP项目的需求而创建的。LMDB通过利用操作系统提供的内存映射文件(Memory-Mapped File)技术,实现了对数据的高效访问和管理。LMDB的核心原理是基于键值对(Key-Value)的存储模型。它使用B+树(B+tree)作为底层数据结构,支持快速的插入、查找和删除操作。此外,LMDB还实现了多版本并发控制(Multi-Version Concurrency Control,MVCC),使得多个事务可以并发地读写数据库,提高了系统的并发性能。

LMDB数据库的基本原理

LMDB数据库的基本架构如下:

包括键-值存储模型、事务处理、B树索引和多版本并发控制。这些原理的结合使得LMDB成为一个高性能、低内存占用和可靠性强的数据库:

1.数据库的键-值存储模型:

LMDB数据库采用了经典的键-值存储模型。每个数据项都由一个唯一的键(Key)和相应的值(Value)组成。通过键,可以快速访问和检索对应的值。这种简单而灵活的数据模型使得LMDB适用于各种应用场景。

2.事务和ACID特性:

LMDB数据库支持事务处理,保证了数据的一致性和可靠性。事务是一系列数据库操作的逻辑单元,要么全部成功执行,要么全部回滚。LMDB遵循ACID特性(原子性、一致性、隔离性和持久性),确保了数据的完整性和可靠性。

3.B+树和多版本并发控制(MVCC):

LMDB使用B+树作为底层的数据结构。B+树是一种高效的平衡搜索树,能够支持快速的插入、查找和删除操作。通过B树索引,LMDB实现了高效的数据访问。此外,LMDB还采用了多版本并发控制(MVCC)机制。当多个事务并发地读写数据库时,MVCC允许它们在不互相干扰的情况下进行操作。每个事务都可以看到数据库的一个一致性快照,即使其他事务同时进行了修改。这种并发控制策略提高了系统的并发性能,避免了常见的并发访问问题。

4.内存映射文件(Memory-Mapped File):

LMDB利用操作系统提供的内存映射文件技术,将数据存储在磁盘上,并将其映射到进程的虚拟内存空间中。这种设计允许LMDB直接访问磁盘上的数据,避免了频繁的磁盘I/O操作,提高了数据的读写效率。此外,LMDB只在需要时将数据加载到内存中,从而降低了内存的占用。

LMDB数据库的特点和优势

本章将介绍LMDB数据库的特点和优势:

1.高性能读写操作:

LMDB数据库以其出色的读写性能而闻名。其采用了高效的B树索引和内存映射文件技术,使得数据的读取和写入操作非常快速。LMDB的读操作是无锁的,不会受到写操作的阻塞,从而保证了高并发环境下的读取效率。

2.低内存占用:

LMDB的内存占用非常低。它利用内存映射文件将数据存储在磁盘上,并且只在需要时将数据加载到内存中。这种设计使得LMDB可以处理大规模的数据集而不会消耗过多的内存资源,适用于内存有限的环境。

3.零拷贝访问:

LMDB通过内存映射文件实现了零拷贝(Zero-Copy)的数据访问方式。它将数据直接映射到内存中,避免了不必要的数据拷贝操作,提高了数据的读写效率。这种零拷贝的设计使得LMDB在处理大型数据集时表现出色。

4.支持多线程和并发访问:

LMDB数据库提供了高效的并发控制机制,允许多个线程同时读写数据库。它通过多版本并发控制(MVCC)来管理数据的一致性,避免了常见的并发访问问题,如死锁和数据冲突。这种特性使得LMDB在并发环境下表现出色,并适用于高并发的应用场景。

5.ACID特性和事务处理:

LMDB数据库支持事务处理,遵循ACID特性(原子性、一致性、隔离性和持久性)。事务提供了数据操作的原子性和一致性,确保了数据的完整性和可靠性。LMDB的事务处理机制使得开发人员可以编写安全和可靠的数据库操作代码。

6.易于使用和部署:

LMDB数据库的使用非常简单和直观。它提供了简洁的API,易于集成到各种编程语言和应用程序中。此外,LMDB是一个轻量级的数据库,没有复杂的依赖关系和部署要求,可以快速部署和运行。

7.可靠性和稳定性:

LMDB经过多年的实际应用和测试,被广泛认可为一种可靠和稳定性。

 

LMDB数据库的使用

LMDB代码下载: https://github.com/LMDB/lmdb

LMDB支持各种语言环境,我们以C语言为例给出简单示例,开发同学可以参考并灵活变通:

  1. 安装和配置LMDB数据库:

        c语言环境将源码解压直接作为lib文件引入即可。

  1. 创建和打开数据库

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)

                 E(mdb_env_create(&env));

                 E(mdb_env_set_maxreaders(env, 1));

                 E(mdb_env_set_mapsize(env, 10485760));

                 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));

 

                 E(mdb_txn_begin(env, NULL, 0, &txn));

                 E(mdb_dbi_open(txn, NULL, 0, &dbi));

  1. 读取数据库

                 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));

                 E(mdb_cursor_open(txn, dbi, &cursor));

                 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {

                         printf("key: %p %.*s, data: %p %.*s\n",

                                  key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,

                                  data.mv_data, (int) data.mv_size, (char *) data.mv_data);

                 }

                 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");

                 mdb_cursor_close(cursor);

                 mdb_txn_abort(txn);

  1. 更新数据库(添加)

            E(mdb_txn_begin(env, NULL, 0, &txn));

            E(mdb_dbi_open(txn, NULL, 0, &dbi));

  

            key.mv_size = sizeof(int);

            key.mv_data = sval;

 

            printf("Adding %d values\n", count);

            for (i=0;i<count;i++) {     

                         sprintf(sval, "%03x %d foo bar", values[i], values[i]);

                         /* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */

                         data.mv_size = sizeof(sval);

                         data.mv_data = sval;

                         if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {

                                  j++;

                                  data.mv_size = sizeof(sval);

                                  data.mv_data = sval;

                         }

            }

            if (j) printf("%d duplicates skipped\n", j);

            E(mdb_txn_commit(txn));

  1. 删除数据库

            for (i= count - 1; i > -1; i-= (rand()%5)) {

                         j++;

                         txn=NULL;

                         E(mdb_txn_begin(env, NULL, 0, &txn));

                         sprintf(sval, "%03x ", values[i]);

                         if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) {

                                  j--;

                                  mdb_txn_abort(txn);

                         } else {

                                  E(mdb_txn_commit(txn));

                         }

            }

总结

本文介绍了LMDB数据库的背景、基本原理、特点和优势,以及其在实际应用中的使用方法。

为了获得最佳性能,我们可以自由调整参数作为性能优化和最佳实践,如设置合理的数据库参数、合理管理事务的范围和生命周期等。LMDB数据库在诸多领域中具有广泛应用的潜力,包括数据分析、机器学习、物联网、金融等。通过充分理解和应用LMDB的特点和优势,开发人员可以构建高性能、可靠和高效的应用系统。

综上所述,LMDB数据库作为一种优秀的键-值存储解决方案,具备强大的性能和灵活的功能,通过深入理解和熟练应用LMDB,我们能够充分发挥其优势,并将其应用于实际的项目中,为应用开发带来更多的便利和效益。

0条评论
0 / 1000
Accelerate
3文章数
0粉丝数
Accelerate
3 文章 | 0 粉丝
Accelerate
3文章数
0粉丝数
Accelerate
3 文章 | 0 粉丝
原创

LMDB基础介绍及使用

2023-06-26 01:17:45
878
0

引言

本人有幸在此前项目中使用LMDB为用户态存储提供高速数据库:原项目为了保证内核clean及方便日后内核升级兼容性,需要将内核态的私有实现全部移植到用户态。为了保证原有内核数据的读取效率不损失,经研究引入LMDB内存映射的方式作为用户态的替代方案存储内核数据得以解决。

引言部分将介绍LMDB数据库的背景和概述,为读者提供对LMDB的基本了解。

LMDB(Lightning Memory-Mapped Database)是一个轻量级、高性能、低内存占用和可靠性的键值存储数据库。它由Symas Corporation开发,最初是为了满足OpenLDAP项目的需求而创建的。LMDB通过利用操作系统提供的内存映射文件(Memory-Mapped File)技术,实现了对数据的高效访问和管理。LMDB的核心原理是基于键值对(Key-Value)的存储模型。它使用B+树(B+tree)作为底层数据结构,支持快速的插入、查找和删除操作。此外,LMDB还实现了多版本并发控制(Multi-Version Concurrency Control,MVCC),使得多个事务可以并发地读写数据库,提高了系统的并发性能。

LMDB数据库的基本原理

LMDB数据库的基本架构如下:

包括键-值存储模型、事务处理、B树索引和多版本并发控制。这些原理的结合使得LMDB成为一个高性能、低内存占用和可靠性强的数据库:

1.数据库的键-值存储模型:

LMDB数据库采用了经典的键-值存储模型。每个数据项都由一个唯一的键(Key)和相应的值(Value)组成。通过键,可以快速访问和检索对应的值。这种简单而灵活的数据模型使得LMDB适用于各种应用场景。

2.事务和ACID特性:

LMDB数据库支持事务处理,保证了数据的一致性和可靠性。事务是一系列数据库操作的逻辑单元,要么全部成功执行,要么全部回滚。LMDB遵循ACID特性(原子性、一致性、隔离性和持久性),确保了数据的完整性和可靠性。

3.B+树和多版本并发控制(MVCC):

LMDB使用B+树作为底层的数据结构。B+树是一种高效的平衡搜索树,能够支持快速的插入、查找和删除操作。通过B树索引,LMDB实现了高效的数据访问。此外,LMDB还采用了多版本并发控制(MVCC)机制。当多个事务并发地读写数据库时,MVCC允许它们在不互相干扰的情况下进行操作。每个事务都可以看到数据库的一个一致性快照,即使其他事务同时进行了修改。这种并发控制策略提高了系统的并发性能,避免了常见的并发访问问题。

4.内存映射文件(Memory-Mapped File):

LMDB利用操作系统提供的内存映射文件技术,将数据存储在磁盘上,并将其映射到进程的虚拟内存空间中。这种设计允许LMDB直接访问磁盘上的数据,避免了频繁的磁盘I/O操作,提高了数据的读写效率。此外,LMDB只在需要时将数据加载到内存中,从而降低了内存的占用。

LMDB数据库的特点和优势

本章将介绍LMDB数据库的特点和优势:

1.高性能读写操作:

LMDB数据库以其出色的读写性能而闻名。其采用了高效的B树索引和内存映射文件技术,使得数据的读取和写入操作非常快速。LMDB的读操作是无锁的,不会受到写操作的阻塞,从而保证了高并发环境下的读取效率。

2.低内存占用:

LMDB的内存占用非常低。它利用内存映射文件将数据存储在磁盘上,并且只在需要时将数据加载到内存中。这种设计使得LMDB可以处理大规模的数据集而不会消耗过多的内存资源,适用于内存有限的环境。

3.零拷贝访问:

LMDB通过内存映射文件实现了零拷贝(Zero-Copy)的数据访问方式。它将数据直接映射到内存中,避免了不必要的数据拷贝操作,提高了数据的读写效率。这种零拷贝的设计使得LMDB在处理大型数据集时表现出色。

4.支持多线程和并发访问:

LMDB数据库提供了高效的并发控制机制,允许多个线程同时读写数据库。它通过多版本并发控制(MVCC)来管理数据的一致性,避免了常见的并发访问问题,如死锁和数据冲突。这种特性使得LMDB在并发环境下表现出色,并适用于高并发的应用场景。

5.ACID特性和事务处理:

LMDB数据库支持事务处理,遵循ACID特性(原子性、一致性、隔离性和持久性)。事务提供了数据操作的原子性和一致性,确保了数据的完整性和可靠性。LMDB的事务处理机制使得开发人员可以编写安全和可靠的数据库操作代码。

6.易于使用和部署:

LMDB数据库的使用非常简单和直观。它提供了简洁的API,易于集成到各种编程语言和应用程序中。此外,LMDB是一个轻量级的数据库,没有复杂的依赖关系和部署要求,可以快速部署和运行。

7.可靠性和稳定性:

LMDB经过多年的实际应用和测试,被广泛认可为一种可靠和稳定性。

 

LMDB数据库的使用

LMDB代码下载: https://github.com/LMDB/lmdb

LMDB支持各种语言环境,我们以C语言为例给出简单示例,开发同学可以参考并灵活变通:

  1. 安装和配置LMDB数据库:

        c语言环境将源码解压直接作为lib文件引入即可。

  1. 创建和打开数据库

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)

                 E(mdb_env_create(&env));

                 E(mdb_env_set_maxreaders(env, 1));

                 E(mdb_env_set_mapsize(env, 10485760));

                 E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));

 

                 E(mdb_txn_begin(env, NULL, 0, &txn));

                 E(mdb_dbi_open(txn, NULL, 0, &dbi));

  1. 读取数据库

                 E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));

                 E(mdb_cursor_open(txn, dbi, &cursor));

                 while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {

                         printf("key: %p %.*s, data: %p %.*s\n",

                                  key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,

                                  data.mv_data, (int) data.mv_size, (char *) data.mv_data);

                 }

                 CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");

                 mdb_cursor_close(cursor);

                 mdb_txn_abort(txn);

  1. 更新数据库(添加)

            E(mdb_txn_begin(env, NULL, 0, &txn));

            E(mdb_dbi_open(txn, NULL, 0, &dbi));

  

            key.mv_size = sizeof(int);

            key.mv_data = sval;

 

            printf("Adding %d values\n", count);

            for (i=0;i<count;i++) {     

                         sprintf(sval, "%03x %d foo bar", values[i], values[i]);

                         /* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */

                         data.mv_size = sizeof(sval);

                         data.mv_data = sval;

                         if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {

                                  j++;

                                  data.mv_size = sizeof(sval);

                                  data.mv_data = sval;

                         }

            }

            if (j) printf("%d duplicates skipped\n", j);

            E(mdb_txn_commit(txn));

  1. 删除数据库

            for (i= count - 1; i > -1; i-= (rand()%5)) {

                         j++;

                         txn=NULL;

                         E(mdb_txn_begin(env, NULL, 0, &txn));

                         sprintf(sval, "%03x ", values[i]);

                         if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) {

                                  j--;

                                  mdb_txn_abort(txn);

                         } else {

                                  E(mdb_txn_commit(txn));

                         }

            }

总结

本文介绍了LMDB数据库的背景、基本原理、特点和优势,以及其在实际应用中的使用方法。

为了获得最佳性能,我们可以自由调整参数作为性能优化和最佳实践,如设置合理的数据库参数、合理管理事务的范围和生命周期等。LMDB数据库在诸多领域中具有广泛应用的潜力,包括数据分析、机器学习、物联网、金融等。通过充分理解和应用LMDB的特点和优势,开发人员可以构建高性能、可靠和高效的应用系统。

综上所述,LMDB数据库作为一种优秀的键-值存储解决方案,具备强大的性能和灵活的功能,通过深入理解和熟练应用LMDB,我们能够充分发挥其优势,并将其应用于实际的项目中,为应用开发带来更多的便利和效益。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0