我已经编写了一些PostgreSQL数据库客户端代码,以使用来自多个客户端的IP地址和主机名表更新中央数据库。有两个表:一个用于保存IP地址和主机名之间的映射,另一个用于保存尚未解析为主机名的IP地址队列。
这是IP地址到主机名的映射表:
CREATE TABLE g_hostmap(
appliance_id INTEGER,
ip INET,
fqdn TEXT,
resolve_time TIMESTAMP,
expire_time TIMESTAMP,
UNIQUE(appliance_id, ip))
这是工作队列表:
CREATE TABLE g_hostmap_work(
ip INET,
input_table TEXT)
每个数据库客户端都从单个工作队列表中提取请求。每个请求都包含一个为其请求主机名的专用IPv4地址。
工作流程如下:每个客户端定期在中央数据库工作队列中查询需要主机名的IP地址列表,对这些地址执行反向DNS查找,然后使用( IP地址,主机名),一次一对。我希望通过尝试同时解析相同的IP地址来减少多个客户端重复工作的可能性。
我将每批更新限制为最大10行或行中工作队列大小的10%。客户的时间安排有些独立。在更新过程中,如何进一步减少对DNS名称服务器和主机名表的争用?我的客户担心会有很多重复的工作。
这是工作队列中项目数量的初始查询:
SELECT COUNT(*)
FROM g_hostmap_work queued
LEFT JOIN g_hostmap cached
ON queued.ip = cached.ip
AND now() < cached.expire_time
这是返回工作队列中项目子集的查询:
SELECT queued.ip, queued.input_table, cached.expire_time
FROM g_hostmap_work queued
LEFT JOIN g_hostmap cached
ON queued.ip = cached.ip
AND now() < cached.expire_time
LIMIT 10
这是单个INSERT语句的示例,该语句使用新的IP地址/主机名映射来更新数据库:
INSERT INTO g_hostmap_20131230 VALUES
(NULL, '192.168.54.133', 'powwow.site', now(), now() + 900 * INTERVAL '1 SECOND')
我会提出一种奇怪的建议。在源表中添加一个auto-inc big int,并使用模除法创建一组10个索引。这是一个简单的测试用例示例:
create table queue (id bigserial, input text);
create index q0 on queue (id) where id%10=0;
create index q1 on queue (id) where id%10=1;
create index q2 on queue (id) where id%10=2;
create index q3 on queue (id) where id%10=3;
create index q4 on queue (id) where id%10=4;
create index q5 on queue (id) where id%10=5;
create index q6 on queue (id) where id%10=6;
create index q7 on queue (id) where id%10=7;
create index q8 on queue (id) where id%10=8;
create index q9 on queue (id) where id%10=9;
insert into queue select generate_series(1,50000),'this';
我们在这里所做的是创建一组索引,该索引对表的1/10进行索引。接下来,我们将选择其中一个范围的一部分进行处理:
begin;
select * from queue where id%10=0 limit 100 for update;
id | input
------+-------
10 | this
20 | this
30 | this
-- do work here --
commit;
现在有趣的部分。如果使用此设置有> 10个工作程序,则只需在数字之间循环,超过10个的工作程序将在上述选择运行更新时等待。但是任何其他数字(1到9)仍然有效。
begin;
select * from queue where id%10=1 limit 100 for update;
id | input
-----+-------
1 | this
11 | this
21 | this
31 | this
-- do work here
commit;
这样,所有工作被分成10个桶。想要更多的水桶?更改%后的数字并增加要匹配的索引数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句