Skip to content

Commit 9e8b0f8

Browse files
authored
perf: accelerate the creation of the consumer cache (#11840)
Signed-off-by: xuruidong <[email protected]>
1 parent 100f290 commit 9e8b0f8

File tree

1 file changed

+81
-38
lines changed

1 file changed

+81
-38
lines changed

apisix/consumer.lua

Lines changed: 81 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ local lrucache = core.lrucache.new({
3636
ttl = 300, count = 512
3737
})
3838

39+
-- Please calculate and set the value of the "consumers_count_for_lrucache"
40+
-- variable based on the number of consumers in the current environment,
41+
-- taking into account the appropriate adjustment coefficient.
42+
local consumers_count_for_lrucache = 4096
43+
3944
local function remove_etcd_prefix(key)
4045
local prefix = ""
4146
local local_conf = config_local.local_conf()
@@ -80,7 +85,53 @@ local function filter_consumers_list(data_list)
8085
return list
8186
end
8287

83-
local function plugin_consumer()
88+
local plugin_consumer
89+
do
90+
local consumers_id_lrucache = core.lrucache.new({
91+
count = consumers_count_for_lrucache
92+
})
93+
94+
local function construct_consumer_data(val, plugin_config)
95+
-- if the val is a Consumer, clone it to the local consumer;
96+
-- if the val is a Credential, to get the Consumer by consumer_name and then clone
97+
-- it to the local consumer.
98+
local consumer
99+
if is_credential_etcd_key(val.key) then
100+
local consumer_name = get_consumer_name_from_credential_etcd_key(val.key)
101+
local the_consumer = consumers:get(consumer_name)
102+
if the_consumer and the_consumer.value then
103+
consumer = core.table.clone(the_consumer.value)
104+
consumer.modifiedIndex = the_consumer.modifiedIndex
105+
consumer.credential_id = get_credential_id_from_etcd_key(val.key)
106+
else
107+
-- Normally wouldn't get here:
108+
-- it should belong to a consumer for any credential.
109+
core.log.error("failed to get the consumer for the credential,",
110+
" a wild credential has appeared!",
111+
" credential key: ", val.key, ", consumer name: ", consumer_name)
112+
return nil, "failed to get the consumer for the credential"
113+
end
114+
else
115+
consumer = core.table.clone(val.value)
116+
consumer.modifiedIndex = val.modifiedIndex
117+
end
118+
119+
-- if the consumer has labels, set the field custom_id to it.
120+
-- the custom_id is used to set in the request headers to the upstream.
121+
if consumer.labels then
122+
consumer.custom_id = consumer.labels["custom_id"]
123+
end
124+
125+
-- Note: the id here is the key of consumer data, which
126+
-- is 'username' field in admin
127+
consumer.consumer_name = consumer.id
128+
consumer.auth_conf = plugin_config
129+
130+
return consumer
131+
end
132+
133+
134+
function plugin_consumer()
84135
local plugins = {}
85136

86137
if consumers.values == nil then
@@ -101,46 +152,21 @@ local function plugin_consumer()
101152
if not plugins[name] then
102153
plugins[name] = {
103154
nodes = {},
155+
len = 0,
104156
conf_version = consumers.conf_version
105157
}
106158
end
107159

108-
-- if the val is a Consumer, clone it to the local consumer;
109-
-- if the val is a Credential, to get the Consumer by consumer_name and then clone
110-
-- it to the local consumer.
111-
local consumer
112-
if is_credential_etcd_key(val.key) then
113-
local consumer_name = get_consumer_name_from_credential_etcd_key(val.key)
114-
local the_consumer = consumers:get(consumer_name)
115-
if the_consumer and the_consumer.value then
116-
consumer = core.table.clone(the_consumer.value)
117-
consumer.modifiedIndex = the_consumer.modifiedIndex
118-
consumer.credential_id = get_credential_id_from_etcd_key(val.key)
119-
else
120-
-- Normally wouldn't get here:
121-
-- it should belong to a consumer for any credential.
122-
core.log.error("failed to get the consumer for the credential,",
123-
" a wild credential has appeared!",
124-
" credential key: ", val.key, ", consumer name: ", consumer_name)
125-
goto CONTINUE
126-
end
127-
else
128-
consumer = core.table.clone(val.value)
129-
consumer.modifiedIndex = val.modifiedIndex
130-
end
131-
132-
-- if the consumer has labels, set the field custom_id to it.
133-
-- the custom_id is used to set in the request headers to the upstream.
134-
if consumer.labels then
135-
consumer.custom_id = consumer.labels["custom_id"]
160+
local consumer = consumers_id_lrucache(val.value.id .. name,
161+
val.modifiedIndex, construct_consumer_data, val, config)
162+
if consumer == nil then
163+
goto CONTINUE
136164
end
137165

138-
-- Note: the id here is the key of consumer data, which
139-
-- is 'username' field in admin
140-
consumer.consumer_name = consumer.id
141-
consumer.auth_conf = config
166+
plugins[name].len = plugins[name].len + 1
167+
core.table.insert(plugins[name].nodes, plugins[name].len,
168+
consumer)
142169
core.log.info("consumer:", core.json.delay_encode(consumer))
143-
core.table.insert(plugins[name].nodes, consumer)
144170
end
145171
end
146172

@@ -150,6 +176,9 @@ local function plugin_consumer()
150176
return plugins
151177
end
152178

179+
end
180+
181+
153182
_M.filter_consumers_list = filter_consumers_list
154183

155184
function _M.get_consumer_key_from_credential_key(key)
@@ -190,20 +219,34 @@ function _M.consumers()
190219
end
191220

192221

193-
local function create_consume_cache(consumers_conf, key_attr)
222+
local create_consume_cache
223+
do
224+
local consumer_lrucache = core.lrucache.new({
225+
count = consumers_count_for_lrucache
226+
})
227+
228+
local function fill_consumer_secret(consumer)
229+
local new_consumer = core.table.clone(consumer)
230+
new_consumer.auth_conf = secret.fetch_secrets(new_consumer.auth_conf, false)
231+
return new_consumer
232+
end
233+
234+
235+
function create_consume_cache(consumers_conf, key_attr)
194236
local consumer_names = {}
195237

196238
for _, consumer in ipairs(consumers_conf.nodes) do
197239
core.log.info("consumer node: ", core.json.delay_encode(consumer))
198-
local new_consumer = core.table.clone(consumer)
199-
new_consumer.auth_conf = secret.fetch_secrets(new_consumer.auth_conf, true,
200-
new_consumer.auth_conf, "")
240+
local new_consumer = consumer_lrucache(consumer, nil,
241+
fill_consumer_secret, consumer)
201242
consumer_names[new_consumer.auth_conf[key_attr]] = new_consumer
202243
end
203244

204245
return consumer_names
205246
end
206247

248+
end
249+
207250

208251
function _M.consumers_kv(plugin_name, consumer_conf, key_attr)
209252
local consumers = lrucache("consumers_key#" .. plugin_name, consumer_conf.conf_version,

0 commit comments

Comments
 (0)