Skip to content

Instantly share code, notes, and snippets.

@chobits
Last active January 22, 2024 07:08
Show Gist options
  • Save chobits/d21f21d83ca24076377ff31db7ab42c1 to your computer and use it in GitHub Desktop.
Save chobits/d21f21d83ca24076377ff31db7ab42c1 to your computer and use it in GitHub Desktop.
perfermance test for kong old and new dns client library
--[[
run it by this command:
$ resty --shdict "kong_dns_cache 10m" --shdict "kong_dns_cache_ipc 10m" ./perf.lua
]]
pcall(require, "luarocks.loader")
require("kong.globalpatches")()
local json = require("cjson").encode
-- hosted in Route53 in the AWS sandbox
local TEST_NS = "192.168.1.1:53"
local TEST_NS = "192.168.5.2:53" -- Kong local official env
local TEST_NSS = { TEST_NS }
local not_found_answers = { errcode = 3, errstr = "not found" }
local a_answers = {{ address = "127.0.0.1", class = 1, ttl = 300, type = 1 }}
-- inject r.query
package.loaded["resty.dns.resolver"] = nil
local resolver = require("resty.dns.resolver")
local query_func = function(self, original_query_func, name, options)
return original_query_func(self, name, options)
end
local old_new = resolver.new
resolver.new = function(...)
local r, err = old_new(...)
if not r then
return nil, err
end
local original_query_func = r.query
r.query = function(self, ...)
return query_func(self, original_query_func, ...)
end
return r
end
--- end of inject r.query
-- restore its API overlapped by the compatible layer
package.loaded["kong.resty.dns_client"] = nil
local client = require("kong.resty.dns_client")
client.resolve = client._resolve
--- TEST APIs
local t
local n
local function test(name, f)
local new_delta, old_delta
print(name)
-- new
local cli = assert(client.new({
nameservers = TEST_NSS,
order = { "LAST", "SRV", "A", "CNAME" },
}))
t = os.clock()
f(function (host) return cli:resolve(host) end)
new_delta = os.clock() - t
print("NEW DNS client consumes: ", new_delta, " 1 try=", new_delta/n *1000, " ms")
-- old
package.loaded["kong.resty.dns.client"] = nil
local cli = require("kong.resty.dns.client")
assert(cli.init({
resolvConf = { "nameserver " .. TEST_NS },
order = { "LAST", "SRV", "A", "CNAME" },
}))
local t = os.clock()
f(function (host) return cli.resolve(host) end)
old_delta = os.clock() - t
print("OLD DNS client consumes: ", old_delta, " 1 try=", old_delta/n *1000, " ms")
-- last
local improved = (n/new_delta)/(n/old_delta) - 1
print(("Improved: %.2f%%\n"):format(improved * 100))
end
--- run test
print("\n\n\n\n\n--- runing perf test ---\n")
--- 100% Hit
n = 100000
local title = "+ hit 100% (miss the first time)"
test(tile, function (cli_resolve)
local answers, err, tries
answers, err, tries = cli_resolve("www.konghq.com")
t = os.clock() -- skip first miss
for i = 1, n do
answers, err, tries = cli_resolve("www.konghq.com")
end
assert(answers[1].name == "www.konghq.com")
end)
--- ?% Hit
--[[
local rate = 9999
local title = ("+ %s%% Hit (Every query to the nameserver succeeds.)"):format(rate)
local count = 0
query_func = function(self, original_query_func, name, options)
count = count + 1
if options.qtype == 33 then -- SRV
return not_found_answers
end
a_answers[1].name = name
return a_answers
--return {{ address = "127.0.0.1", class = 1, ttl = 300, type = 1, name = name }}
end
test(title, function (cli_resolve)
local answers, err, tries, host
answers, err, tries = cli_resolve("www.konghq.com")
t = os.clock() -- skip first miss
count = 0
for i = 1, n do
host = ((i % 10000) < rate) and "www.konghq.com" or i .. ".konghq.com"
answers, err, tries = cli_resolve(host)
--assert(answers[1].name == host)
end
print(" rate:", 1 - count / (2 * n))
-- assert(count == 2 * n)
end)
]]
--- 0% Hit
n = 10000
local title = "+ 0% Hit (Every query to the nameserver succeeds.)"
local count = 0
query_func = function(self, original_query_func, name, options)
count = count + 1
if options.qtype == 33 then -- SRV
return not_found_answers
end
a_answers[1].name = name
return a_answers
end
test(title, function (cli_resolve)
local answers, err, tries
count = 0
for i = 1, n do
answers, err, tries = cli_resolve(i .. ".konghq.com")
end
assert(answers[1].name == n .. ".konghq.com")
assert(count == 2 * n)
end)
@chobits
Copy link
Author

chobits commented Jan 21, 2024

  1. My test branch kong-ce refactor/dns_client from this PR Kong/kong#12305
  2. git checkout to this branch refactor/dns_client
  3. Go into Bazel development env: . bazel-bin/build/kong-dev-venv.sh
  4. Run it with the command: resty --shdict "kong_dns_cache 10m" --shdict "kong_dns_cache_ipc 10m" ./perf.lua

Result like :

(kong-dev) xc kong $ resty --shdict "kong_dns_cache 10m" --shdict "kong_dns_cache_ipc 10m" /Users/xc/work/snippets/openresty/dns_client_test/perf.lua 2>/dev/null

--- runing perf test ---

NEW DNS client consumes: 0.020167 1 try=0.00020167 ms
OLD DNS client consumes: 0.054615 1 try=0.00054615 ms
Improved: 170.81%

+ 0% Hit (Every query to the nameserver succeeds.)
NEW DNS client consumes: 0.886844 1 try=0.0886844 ms
OLD DNS client consumes: 0.708964 1 try=0.0708964 ms
Improved: -20.06%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment