MaxMind 的 GeoIP C 实现线程安全吗?

Posted

技术标签:

【中文标题】MaxMind 的 GeoIP C 实现线程安全吗?【英文标题】:Is MaxMind's GeoIP C Implementation Thread Safe? 【发布时间】:2011-12-05 16:44:16 【问题描述】:

假设一个进程在许多单独的线程中使用MaxMind GeoIP C API。并发呼叫GeoIP_record_by_addr 安全吗?假设这是唯一同时访问数据的进程,并且正在使用单个 GeoIP 句柄。

提前致谢!

【问题讨论】:

您是否在线程之间共享一个 geoip 句柄? 【参考方案1】:

根据 MaxMind 自己的文档,如果您避免使用 GEOIP_CHECK_CACHE 选项,它只是线程安全的。这意味着库不会通过 mtime 检查检查磁盘上的数据库更新。对于长期运行的应用程序,如果您需要新鲜数据,您必须:

定期重启应用 进行您自己的 mtime 检查并通过以下方式重新加载 GeoIP_open() 类型的调用,但这需要您自己设置 互斥锁以保护共享 GeoIP 的重新加载/替换 句柄,所以那时你正在做完整的线程安全 自己保护。您不妨打开 GEOIP_CHECK_CACHE 并使用互斥锁首先保护所有内容,避免编写自己的重新加载代码。

无论 GEOIP_CHECK_CACHE 如何,另外两个次要功能也不是线程安全的:

如果您使用网络掩码信息(并不是每个人都这样做),查找函数只会通过在 GeoIP 句柄本身上设置 gi->netmask 来返回该信息,因此显然共享句柄的网络掩码不会总是为来自同一线程的“最近”查找。 显然,对 GeoIPCity (GeoIP_next_record()) 的迭代器接口的任何使用也是不安全的,因为迭代器状态存储在共享句柄中。

在我的简要分析中可能遗漏了其他问题,但恕我直言,使用每个线程的 GeoIP 句柄或将对共享句柄的所有访问权限包装在您自己的互斥锁中更为实用,然后您可以使用所有功能并拥有它为您执行基于 mtime 的重新加载。

【讨论】:

【参考方案2】:

我有时间研究 GeoIP API,它对数据库的处理似乎是线程安全的。预读或内存访问。

【讨论】:

以上是关于MaxMind 的 GeoIP C 实现线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

导入 com.maxmind.geoip2 无法解析

MaxMind 的 GeoIP 数据库

Nginx geoip模块

MaxMind:将 GeoIP2 mmdb 加载到内存中以便快速读取

无法下载 GeoIP 数据 - Nginx >> GeoIP - 404 错误 - 正在解决 geolite.maxmind.com (geolite.maxmind.com)

MaxMind GeoIP2 没有 IPv6 的结果?