簡體   English   中英

Python,SQLAlchemy:如何提高加密的sqlite數據庫的性能?

[英]Python, sqlalchemy: how to improve performance of encrypted sqlite database?

我有一個簡單的服務應用程序:python,龍卷風Web服務器,sqlite數據庫。 數據庫已加密。

問題在於,即使處理非常簡單的http請求也要花費大約300毫秒。

從日志中我可以看到,不管第一個請求多么簡單,大部分時間都用於處理第一個sql請求。 后續sql請求的處理速度更快。 但是隨后服務器開始處理下一個http請求,並且第一個sql請求再次非常慢。

如果我關閉數據庫加密,問題就不存在了:sql請求的處理時間不取決於請求是否是第一個,並且我的服務器響應時間減少了10到15。

我不太了解發生了什么。 看起來sqlalchemy每次啟動新會話時都會讀取並解密數據庫文件。 有什么辦法可以解決此問題?

由於pysqlite或sqlite3模塊的工作方式,SQLAlchemy 默認將NullPool與基於文件的數據庫一起使用 這就解釋了為什么每個請求都對數據庫進行解密: NullPool在關閉連接時會丟棄它們。 這樣做的原因是pysqlite的默認行為是禁止在多個線程中使用連接,並且無需加密即可快速創建新連接。

Pysqlite確實有一個未記錄的標志check_same_thread可用於禁用該檢查,但應謹慎處理線程之間的共享連接,而SQLAlchemy文檔也提到了NullPool與SQLite的文件鎖定配合NullPool很好。

根據您的Web服務器,您可以使用SingletonThreadPool ,這意味着線程中的所有連接都是相同的連接:

engine = create_engine('sqlite:///my.db',
                       poolclass=SingletonThreadPool)

如果您喜歡冒險並且Web服務器在使用時(例如,使用作用域的會話)在線程之間不共享連接/會話,那么您可以嘗試使用與check_same_thread=False配對的另一種池策略:

engine = create_engine('sqlite:///my.db',
                       poolclass=QueuePool,
                       connect_args={'check_same_thread':False})

要加密數據庫sqlcipher,請使用我提供的密碼創建一個密鑰。 此操作在設計上會消耗資源。

但是可以使用不是密碼短語,而是使用256位原始密鑰。 在這種情況下,sqlcipher不必生成加密密鑰。

最初,我的代碼是:

session.execute('PRAGMA KEY = "MY_PASSPHRASE";')

要使用原始密鑰,我將此行更改為:

session.execute('''PRAGMA KEY = "x'<the key>'";''')

其中<the key>是64個字符的十六進制長字符串。

結果是小請求的速度提高了20倍以上。

僅供參考:將數據庫轉換為使用新的加密密鑰,應執行以下命令:

PRAGMA KEY = ""MY_PASSPHRASE";
PRAGMA REKEY = "x'<the key>'";

相關問題: python,sqlite,sqlcipher:處理首次請求的性能很差

有關sqlcipher命令以及密鑰和原始密鑰之間的區別的一些信息: https ://www.zetetic.net/sqlcipher/sqlcipher-api/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM