Last active
August 14, 2024 07:35
-
-
Save chobits/d21f21d83ca24076377ff31db7ab42c1 to your computer and use it in GitHub Desktop.
Revisions
-
chobits revised this gist
Aug 14, 2024 . 1 changed file with 51 additions and 70 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,27 +1,23 @@ --[[ run it by this command: $ resty --shdict "kong_dns_cache 10m" ./perf.lua ]] setmetatable(_G, nil) -- disable the _G write guard alert log introduced in OpenResty 1.15.8.1 pcall(require, "luarocks.loader") require("kong.globalpatches")() local json = require("cjson").encode 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 local resolver = require("resty.dns.resolver") local query_func = function(self, original_query_func, name, options) return original_query_func(self, name, options) end @@ -38,99 +34,84 @@ resolver.new = function(...) end return r end resolver.tag = "modified" --- end of inject r.query -- restore its API overlapped by the compatible layer package.loaded["kong.resty.dns_client"] = nil local client = require("kong.dns.client") client.resolve = client._resolve _G.busted_legacy_dns_client = true package.loaded["kong.resty.dns.client"] = nil local dns_client = require("kong.resty.dns.client") --- TEST APIs local n local t local function measure_function_time(f) t = os.clock() f() local delta = os.clock() - t print(string.format(" run resolve() %d times: %.4f s; avg: %.6f ms per calls", n, delta, delta/n *1000)) return delta end local function test(name, f) local new_delta, old_delta print(name) -- new local cli = assert(client.new({ family = { "SRV", "A" }, })) print("+ NEW DNS client") local new_delta = measure_function_time(function () f(function (host) return cli:resolve(host, nil, nil, {}) end) end) -- print("+ stats: ", json(cli.stats)) -- old assert(dns_client.init({ order = { "LAST", "SRV", "A", "CNAME" }, })) print("+ OLD DNS client") local old_delta = measure_function_time(function () f(function (host) return dns_client.resolve(host, nil, nil, {}, nil) end) end) -- last local improved = (1/(new_delta/n))/(1/(old_delta/n)) - 1 print(("+ Improved: %.2f%%\n"):format(improved * 100)) end --- run test print("\n--- runing perf test ---\n") --- 100% Hit n = 10000000 local title = "+ 100% hit (miss the first time)" test(title, function (cli_resolve) local answers, err, tries -- skip first miss -- answers, err, tries = cli_resolve("www.konghq.com") assert(not err, "err:".. tostring(err) .. " tries:" .. json(tries)) t = os.clock() -- run HIT query for i = 1, n do answers, err, tries = cli_resolve("www.konghq.com") end assert(not err) assert(answers[1].name == "www.konghq.com") end) --- 0% Hit n = 100000 local title = "+ 0% Hit (Every query to the nameserver succeeds.)" local count = 0 @@ -150,5 +131,5 @@ test(title, function (cli_resolve) answers, err, tries = cli_resolve(i .. ".konghq.com") end assert(answers[1].name == n .. ".konghq.com") assert(count == n or count == n*2) end) -
chobits revised this gist
Jan 22, 2024 . 1 changed file with 62 additions and 174 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,44 +6,22 @@ $ resty --shdict "kong_dns_cache 10m" --shdict "kong_dns_cache_ipc 10m" ./perf.l ]] 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 @@ -60,207 +38,117 @@ resolver.new = function(...) 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 revised this gist
Jan 21, 2024 . 1 changed file with 8 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,10 @@ --[[ 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")() @@ -256,4 +263,4 @@ if resolv_path then end if hosts_path then os.remove(hosts_path) end -
chobits created this gist
Jan 21, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,259 @@ pcall(require, "luarocks.loader") require("kong.globalpatches")() local _writefile = require("pl.utils").writefile local tmpname = require("pl.path").tmpname -- hosted in Route53 in the AWS sandbox local TEST_DOMAIN = "kong-gateway-testing.link" local TEST_NS = "198.51.100.0:53" local TEST_NS = "192.168.5.2:53" -- Kong local official env local TEST_NS = "192.168.1.1:53" 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 }} local resolv_path, hosts_path local function writefile(path, text) _writefile(path, type(text) == "table" and table.concat(text, "\n") or text) end -- create temp resolv.conf and hosts local resolv_path = tmpname() local hosts_path = tmpname() ngx.log(ngx.DEBUG, "create temp resolv.conf:", resolv_path, " hosts:", hosts_path) -- inject r.query package.loaded["resty.dns.resolver"] = nil local resolver = require("resty.dns.resolver") -- replace this `query_func` upvalue to spy on resolver query calls. 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 -- 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 package.loaded["kong.resty.dns.client"] = nil local old_client = require("kong.resty.dns.client") --- TEST apis local t local function client_new(opts) opts = opts or {} opts.resolv_conf = resolv_path opts.hosts = hosts_path return client.new(opts) end local n local new_delta local old_delta local function test_new(name, f) print("[New DNS client]", name) writefile(resolv_path, { "nameserver " .. TEST_NS }) local cli = assert(client_new({ order = { "LAST", "SRV", "A", "AAAA", "CNAME" } })) t = os.clock() f(cli) new_delta = os.clock() - t print("It consumes: ", new_delta, "s") end local function test_old(name, f) print("[Old DNS client]", name) assert(old_client.init({ resolvConf = { "nameserver " .. TEST_NS, order = { "LAST", "SRV", "A", "CNAME" } }})) local t = os.clock() f() old_delta = os.clock() - t print("It consumes: ", old_delta, "s") 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") -------------------- n = 1000000 local title = "+ REAL SENARIO: miss the first time, hit 99%" test_new(title, function (cli) 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) test_old(title, function () local answers, err, tries answers, err, tries = old_client.resolve("www.konghq.com") t = os.clock() -- skip first miss for i = 1, n do answers, err, tries = old_client.resolve("www.konghq.com") end assert(answers[1].name == "www.konghq.com") end) test_new(title .. " qtype=A", function (cli) local answers, err, tries answers, err, tries = cli:resolve("www.konghq.com", {qtype=1}) t = os.clock() -- skip first miss for i = 1, n do answers, err, tries = cli:resolve("www.konghq.com", {qtype=1}) end assert(answers[1].name == "www.konghq.com") end) test_old(title .. "qtype=A", function () local answers, err, tries answers, err, tries = old_client.resolve("www.konghq.com", {qtype=1}) t = os.clock() -- skip first miss for i = 1, n do answers, err, tries = old_client.resolve("www.konghq.com", {qtype=1}) end assert(answers[1].name == "www.konghq.com") end) -------------------- n = 10000 local title = "+ 100% miss, query suceeds (subtracting network I/O time.)" local count = 0 query_func = function(self, original_query_func, name, options) count = count + 1 if options.qtype == 33 then return not_found_answers end a_answers[1].name = name return a_answers end test_new(title, function (cli) 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) test_old(title, function () local answers, err, tries count = 0 for i = 1, n do answers, err, tries = old_client.resolve(i .. ".konghq.com") end assert(answers[1].name == n .. ".konghq.com") assert(count == 2 * n) end) test_new(title .. " qtype=A", function (cli) local answers, err, tries count = 0 for i = 1, n do answers, err, tries = cli:resolve(i .. ".konghq.com", {qtype=1}) end assert(answers[1].name == n .. ".konghq.com") assert(count == n) end) test_old(title .. " qtype=A", function () local answers, err, tries count = 0 for i = 1, n do answers, err, tries = old_client.resolve(i .. ".konghq.com", {qtype =1}) end assert(answers[1].name == n .. ".konghq.com") assert(count == n) end) -------------------- n = 10000 local title = "+ 100% miss, query gets empty record (subtracting network I/O time)." local count = 0 query_func = function(self, original_query_func, name, options) -- print(" query: ", name .. options.qtype) count = count + 1 return not_found_answers end test_new(title, function (cli) local answers, err, tries count = 0 for i = 1, n do answers, err, tries = cli:resolve(i .. ".konghq.com") end assert(not answers) assert(count == 4 * n) end) test_old(title, function () local answers, err, tries count = 0 for i = 1, n do answers, err, tries = old_client.resolve(i .. ".konghq.com") end --assert(not answers) assert(count == 4 * n) end) test_new(title .. " qtype=A", function (cli) local answers, err, tries count = 0 for i = 1, n do answers, err, tries = cli:resolve(i .. ".konghq.com", {qtype=1}) end assert(not answers) assert(count == n) end) test_old(title .. " qtype=A", function () local answers, err, tries count = 0 for i = 1, n do answers, err, tries = old_client.resolve(i .. ".konghq.com", {qtype=1}) end --assert(not answers) assert(count == n) end) --- end if resolv_path then os.remove(resolv_path) end if hosts_path then os.remove(hosts_path) end