Linux中国

Python 内存数据库 CyberDB 使用实例

概括

CyberDB 是一个轻量级的 Python 内存数据库。它旨在利用 Python 内置数据结构字典、列表作数据存储,通过 TCP 套接字高效通信,并提供了数据持久化。该数据库的亮点在于它使用了 Pythonic 的方式编程,你可以像使用字典和列表一样使用 CyberDB

现在我们把 CyberDB 带到能发挥其作用的地方,在生产环境中将 CyberDB 作为 Flask 的内存数据库,使用 Gunicorn 运行,并实现多进程间的通信。

这篇文章通过一个尽可能精简的 Flask 实例讲解,不会涉及复杂的 Web 知识。核心思路为 CyberDB + Gunicorn + Gevent + Flask(多进程 + 协程),启动一个 CyberDB 服务器,使用 Gunicorn 多进程运行 Flask 实例,每个进程的实例通过 Gevent 运行,进程中使用 CyberDB 客户端连接至内存数据库,由此实现对 CyberDB 数据库的高并发访问。

源码解析

文章使用 PyPy 运行,同样适用 CPython。

运行环境: Debian 10, Python 3.8.12, PyPy 7.3.7

此项目的目录结构

.
├── app.py
├── cyberdb_init.py
├── cyberdb_serve.py
├── requirements.txt
└── venv

我们通过列举每个文件的内容顺序讲解 CyberDB 的核心操作。

文件 requirements.txt

CyberDB>=0.7.1
Flask==2.1.1
gevent==21.12.0
gunicorn==20.1.0

这是此项目的依赖。这篇文章不是 Python 基础教程,如果你不清楚,请查询相关文档创建虚拟环境 venv 目录并安装 requirements.txt 中的依赖。

生成 venv 目录并安装好依赖后,下面所有操作都在激活的虚拟环境中运行。

文件 cyberdb_init.py

功能:初始化 CyberDB 的表结构,只在第一次运行时使用,后续不再使用。

import time

import cyberdb

db = cyberdb.Server()
# 配置 CyberDB 服务端的 地址、端口、密码。
db.start(host='127.0.0.1', port=9980, password='123456')

# 待服务端启动后,连接 CyberDB 服务端。
time.sleep(3)
client = cyberdb.connect(host='127.0.0.1', port=9980, password='123456')
# 生成 proxy 对象。
with client.get_proxy() as proxy:
    # 创建类型为 CyberDict 的表 centre,并初始化内容。
    proxy.create_cyberdict('centre')
    centre = proxy.get_cyberdict('centre')
    centre['content'] = 'Hello CyberDB!'

# 将 CyberDB 保存至 data.cdb 。
db.save_db('data.cdb')

在项目根目录执行

python cyberdb_init.py

以完成 CyberDB 数据库表的初始化。

它会在 CyberDB 中创建了一个名为 centre、类型为 CyberDict 的表;初始化 content 键的值为 Hello CyberDB!;最后将 CyberDB 数据库保存至硬盘(在项目根目录生成了名为 data.cdb 的文件)。

文件 cyberdb_serve.py

功能:运行 CyberDB 服务端。

import cyberdb

def main():
    # 后台运行 CyberDB 服务端,设置相关信息。
    db = cyberdb.Server()
    # 从硬盘读取 data.cdb 至 CyberDB。
    db.load_db('data.cdb')
    # 每 300 秒备份一次数据库。
    db.set_backup('data.cdb', cycle=300)
    db.run(
        host='127.0.0.1', # TCP 运行地址
        port=9980, # TCP 监听端口
        password='hWjYvVdqRC', # 数据库连接密码
        max_con=10000, # 最大并发数
        encrypt=True, # 加密通信
        print_log=False # 不打印日志
    )

if __name__ == '__main__':
    main()

在项目根目录执行

python cyberdb_serve.py

以运行 CyberDB 服务端。

此处设置了 encrypt=True ,CyberDB 会将 TCP 通信内容使用 AES-256 算法加密。开启 encrypt=True 后,CyberDB 仅允许白名单中的 IP 通信,默认白名单为 ['127.0.0.1'](查看白名单 设置方法)。一般,若只需在本地进程间通信,无需开启 encrypt=True 和设置白名单,只有远程通信时需要此操作。

文件 app.py

功能:运行 Flask 实例和 CyberDB 客户端。

import cyberdb
from flask import Flask, g

# 连接 CyberDB 并生成客户端实例。
client = cyberdb.connect(
    host='127.0.0.1', 
    port=9980, 
    password='hWjYvVdqRC',
    # 服务端若加密,客户端必须加密,反之亦然。
    encrypt=True,
    # 每个连接若超过900秒无操作,将舍弃该连接。
    # 连接由连接池智能管理,无需关注细节。
    time_out=900
)

# 创建 Flask 实例,此部分请参考 
# Flask 文档 https://flask.palletsprojects.com/
app = Flask(__name__)

@app.before_request
def before_request():
    # 每次请求执行前生成 proxy 对象。
    g.proxy = client.get_proxy()
    # 从连接池获取连接。
    g.proxy.connect()

@app.get("/")
def hello_world():
    # 从数据库获取 centre 表。
    centre = g.proxy.get_cyberdict('centre')

    return {
        'code': 1,
        'content': centre['content']
    }

@app.teardown_request
def teardown_request(error):
    # 每次请求执行后归还连接至连接池。
    g.proxy.close()

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8000)

该模块会在每次请求执行前(before_request())使用 client.get_proxy() 获取 proxy 对象,每个获取的 proxy 对象可以绑定一个 TCP 连接,此处使用 proxy.connect() 从连接池获取连接。视图函数 hello_world() 中,由 proxy 获取的对象 centre,与 proxy 共用同一个连接,proxy 的连接释放后,centre 也会失去连接。在每次请求后(teardown_request())使用 proxy.close() 方法释放 proxy 绑定的连接,归还至连接池。

cyberdb.connecttime_out 参数表示连接池中每个连接的超时时间,此处每个连接超过 900 秒无操作将被舍弃。若不设置该参数,连接池的每个连接会维持到失效为止。

使用 Gunicorn 运行 Flask 实例

Gunicorn 是一个用于 UNIX 的 Python WSGI HTTP 服务器,通常在生产环境使用,可以利用多核 CPU 。

Gevent 是一个基于协程的 Python 网络库。Gevent 会更改 CyberDB 客户端的底层套接字通信,使之支持协程。

在项目根目录运行

gunicorn -w 4 -b 127.0.0.1:8000 -k gevent app:app

使用 4 进程、Gevent 启动 Flask 实例。

浏览器访问 127.0.0.1:8000 ,得到如下响应:

{"code":1,"content":"Hello CyberDB!"}

参考信息

CyberDB 源码: https://github.com/Cyberbolt/CyberDB

总结

通过此例,你可以把 CyberDB 部署到更复杂的 Web 环境中,充分享受内存的低延迟特性。CyberDB 的核心是以 Pythonic 的方式编程,你可以在任何 Python 代码中将 CyberDB 作为内存数据库。

作者简介:

Cyberbolt:一个自由的 Python 开发者。

via: https://www.cyberlight.xyz/static/cyberdb-chn/tutorial/flask/

作者:Cyberbolt 编辑:wxy

本文由贡献者投稿至 Linux 中国公开投稿计划,采用 CC-BY-SA 协议 发布,Linux中国 荣誉推出


本文转载来自 Linux 中国: https://github.com/Linux-CN/archive

对这篇文章感觉如何?

太棒了
0
不错
0
爱死了
0
不太好
0
感觉很糟
0
雨落清风。心向阳

    You may also like

    Leave a reply

    您的邮箱地址不会被公开。 必填项已用 * 标注

    这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理

    More in:Linux中国

    Linux中国

    关于Linux防火墙iptables的面试问答

    Nishita Agarwal是Tecmint的用户,她将分享关于她刚刚经历的一家公司(印度的一家私人公司Pune)的面试经验。在面试中她被问及许多不同的问题,但她是iptables方面的专家,因此她想分享这些关于iptables的问题和相应的答案给那些以后可能会进行相关面试的人。 所有的问题和相应的答案都基于Nishita Agarwal的记忆并经过了重写。 嗨,朋友!我叫Nishita Agarwal。我已经取得了理学学士学位,我的专业集中在UNIX和它的变种(BSD,Linux)。它们一直深深的吸引着我。我在存储方面有1年多的经验。我正在寻求职业上的变化,并将供职于印度的P
    Linux中国

    Lets Encrypt 已被所有主流浏览器所信任

    旨在让每个网站都能使用 HTTPS 加密的非赢利组织 Lets Encrypt 已经得了 IdenTrust的交叉签名,这意味着其证书现在已经可以被所有主流的浏览器所信任。从这个里程碑事件开始,访问者访问使用了Lets Encrypt 证书的网站不再需要特别配置就可以得到 HTTPS 安全保护了。 Lets Encrypt 的两个中级证书 ...
    Linux中国

    SSL/TLS 加密新纪元 – Lets Encrypt

    根据 Let's Encrypt 官方博客消息,Let's Encrypt 服务将在下周(11 月 16 日)正式对外开放。 Let's Encrypt 项目是由互联网安全研究小组(ISRG,Internet Security Research Group)主导并开发的一个新型数字证书认证机构(CA,Certificate ...