Dns 节点解析器:模块中的并行性和并发性 上下文

Dns 节点解析器:模块中的并行性和并发性 上下文,dns,Dns,亲爱的结解析器用户,我有一个finish阶段 static knot_layer_api_t _layer = { .finish = &collect, }; collect函数static int collect(knot_layer_t*ctx){的目的是通过REST API询问外部oraculum是否列出了包含恶意软件或网络钓鱼活动的特定域,以及是否应该对其进行解析或隐藏 只要结解析程序不是数百个并发DNS请求的目标,它就可以正常工作。 当这种情况发生时,考虑到o

亲爱的结解析器用户,我有一个
finish
阶段

 static knot_layer_api_t _layer = {
     .finish = &collect,
 };
collect函数
static int collect(knot_layer_t*ctx){
的目的是通过REST API询问外部oraculum是否列出了包含恶意软件或网络钓鱼活动的特定域,以及是否应该对其进行解析或隐藏

只要结解析程序不是数百个并发DNS请求的目标,它就可以正常工作。 当这种情况发生时,考虑到oraculum的API响应时间变化,有时可能长达数十到数百毫秒, 客户机开始暂时感觉到来自结解析程序的响应时间很长,远远超过与oraculum的API通信时设置的硬超时

可能的问题 我认为事实上 使模块的实现效率非常低,因为查询正在排队并由 模块一个接一个(在特定过程中)。这意味着如果
n
查询几乎达到oraculum的API超时限制
t
,客户端 将其
n+1
查询发送到此特定的kresd进程的人,将感觉到累积
n*t
的响应时间非常长

或者会吗?我完全疯了吗

当我使用goroutines在gonds中原型化类似的功能时,gonds服务器(以可怕的CPU使用为代价)让很多人失望 DNS客户端的查询与Oracculum对话,并“同时”返回客户端

问题:
  • 使用Apache Portable Runtime线程或OpenMP线程并开始在模块中隐藏API的响应时间是否合适?这不是一个完整的结解析程序反模式吗
  • 我将oraculum的API响应缓存在一个简单的内存中临时LRU缓存中,该缓存驻留在每个kresd进程中。是否可以使用kresd自己的MVCC缓存来代替我的任意结构
  • 是否有可能是其他地方的问题,例如,结解析程序不希望在
    finish
    层中有任何阻塞延迟,因此一些网络队列被填充,随后的DNS查询被拒绝和/或无法忍受的延迟
感谢这里的指针(双关语)

Knot DNS developer(但不是解析器)。我认为你是对的。我的理解是层代码在守护进程线程中同步执行。异步仅出现在解析器网络I/O级别

在内部,服务器运行libuv循环,该循环仅对libuv提供的原语(套接字、计时器、信号等)上的事件执行回调。问题在于,您无法在任意点暂停正在运行的回调(C函数),返回libuv循环,并在稍后的某个点继续执行回调

也就是说,异步等待事件只能在预期的情况下发生,而代码驱动层并不期望这样

答案:

  • 我对libapr或OpenMP不是很熟悉,但我认为如果不重新修改层接口并使其异步化,就无法真正解决这个问题

  • 共享缓存肯定可以使用。如果你找不到API,jolly Knot DNS人员会乐意接受补丁或帮助你编写补丁

  • 正是这种情况。结解析器不希望层完成回调中出现阻塞代码


这里有一个结解析器开发者:-)(我也重复了Jan已经回答过的一些问题。)

  • 通过进程进行扩展可以很好地工作。等待来自名称服务器的响应是由libuv完成的(通过事件循环和回调,都在单个线程中)
  • 由于采用单线程方式,因此不应(在I/O上)阻止任何层函数,因为这会使其上的所有内容都被阻止。AFAIK目前唯一真正发生这种情况的情况是缓存(部分)被交换出去
  • 在继续处理层之前,当需要子请求时,它会使用屈服状态,但我目前不知道其工作的细节。我认为它不直接适用,因为恢复层目前似乎只由子请求完成触发
  • 缓存:如果将模块放在rrcache模块之前并更改RRset,它将被缓存并已更改