1 回答
TA贡献1802条经验 获得超6个赞
我最近在 Go 中为网络应用程序评估了 SQLite3 的性能,并了解到它需要一些设置才能远程使用。
打开预写日志
您需要使用 WAL PRAGMA journal_mode=WAL
。这就是为什么你的表现如此糟糕的主要原因。使用 WAL,我可以在几秒钟内完成 10000 次没有事务的并发写入。在交易中,这将是闪电般的快速。
禁用连接池
我使用mattn/go-sqlite3
它打开一个带有SQLITE_OPEN_FULLMUTEX
标志的数据库。这意味着每个 SQLite 调用都会被锁保护。一切都会被序列化。这实际上就是你想要的 SQLite。在这种情况下,Go 的问题是您会收到随机错误,告诉您数据库已锁定。原因是因为sql/DB
内部的工作方式。它内部为您管理连接池,因此它将打开多个 SQLite 连接,而您不想这样做。为了解决这个问题,我基本上必须禁用池。打电话db.SetMaxOpenConns(1)
,它会工作。即使在具有数万次并发读取和写入的非常高的负载下,它也能毫无问题地工作。
其他解决方案可能是使用SQLITE_OPEN_NOMUTEX
在多线程模式下运行 SQLite 并让它为您管理。但是 SQLite 在多线程应用程序中并不真正起作用。读取可以并行发生,但一次只能写入一次。您会偶尔遇到busy
SQLite 完全正常的错误,但需要您对它们做些什么——当发生这种情况时,您可能不想完全停止写入操作。这就是为什么大多数时候人们要么同步地使用 SQLite,要么通过将调用发送到一个单独的线程来为 SQLite 工作。
- 1 回答
- 0 关注
- 357 浏览
添加回答
举报