Skip to content

Commit b0a5e9c

Browse files
authored
fix(*) use dedicated shm for rate-limiting plugins
This is part of a series of fixes: - thibaultcha/lua-resty-mlcache#41 - thibaultcha/lua-resty-mlcache#42 - #3311 - #3341 Context ------- In the `local` mode of the rate-limiting plugins, storing the rate-limiting counters in the same shm used by Kong's database cache is too invasive for the underlying shm, especially when the rate-limiting plugins are used with a `seconds` precision. On top of exhausting the database cache slots, this approach also generates some form of fragmentation in the shm. This is due to the side-by-side storage of values with sizes of different orders of magnitude (JSON strings vs. an incremented double) and the LRU eviction mechanism. When the shm is full and LRU kicks-in, it is highly probable that several rate-limiting counters will be evicted (due to their proliferation), thus not freeing enough space to store the retrieved data, causing a `no memory` error to be reported by the shm. Solution -------- Declaring shms that are only used by some plugins is not very elegant. Now, all users (even those not using rate-limiting plugins) have to pay a memory cost (although small). Unfortunately, and in the absence of a more dynamic solution to shm configuration such as a more dynamic templating engine, or a `configure_by_lua` phase, this is the safest solution. Size rationale -------------- Running a script generating similar keys and storing similar values (double) indicates that an shm with 12Mb should be able to store about ~48,000 of those values at once. It is important to remind ourselves that one Consumer/IP address might use more than one key (in fact, one per period configured on the plugin), and both the rate-limiting and response-ratelimiting plugins at once, and they use the same shms. Even considering the above statements, ~48,000 keys per node seems somewhat reasonable, considering keys of `second` precision will most likely fill up the shm and be candidates for LRU eviction. Our concern lies instead around long-lived limits (and thus, keys) set by the user. Additionally, a future improvement upon this will be the setting of the `init_ttl` argument for the rate-limiting keys, which will help **quite considerably** in reducing the footprint of the plugins on the shm. As of this day, this feature has been contributed to ngx_lua but not released yet: openresty/lua-nginx-module#1226 Again, this limit only applies when using the **local** strategy, which also likely means that a load-balancer is distributing traffic to a pool of Kong nodes with some sort of consistent load-balancing technique. Thus considerably reducing the number of concurrent Consumers a given node needs to handle at once. See also -------- Another piece of the fixes for the `no memory` errors resides in the behavior of the database caching module upon a full shm. See: thibaultcha/lua-resty-mlcache#41 This patch reduces the likeliness of a full shm (by a lot!), but does not remove it. The above patch ensures a somewhat still sane behavior would the shm happen to be full again. Fix #3124 Fix #3241 From #3311
1 parent 8338d52 commit b0a5e9c

File tree

5 files changed

+5
-2
lines changed

5 files changed

+5
-2
lines changed

kong/constants.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,6 @@ return {
8383
"kong_process_events",
8484
"kong_cluster_events",
8585
"kong_healthchecks",
86+
"kong_rate_limiting_counters",
8687
},
8788
}

kong/plugins/rate-limiting/policies/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local reports = require "kong.core.reports"
66

77

88
local ngx_log = ngx.log
9-
local shm = ngx.shared.kong_cache
9+
local shm = ngx.shared.kong_rate_limiting_counters
1010
local pairs = pairs
1111
local fmt = string.format
1212

kong/plugins/response-ratelimiting/policies/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local reports = require "kong.core.reports"
66

77

88
local ngx_log = ngx.log
9-
local shm = ngx.shared.kong_cache
9+
local shm = ngx.shared.kong_rate_limiting_counters
1010
local pairs = pairs
1111
local fmt = string.format
1212

kong/templates/nginx_kong.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ lua_shared_dict kong_db_cache_miss 12m;
3434
lua_shared_dict kong_process_events 5m;
3535
lua_shared_dict kong_cluster_events 5m;
3636
lua_shared_dict kong_healthchecks 5m;
37+
lua_shared_dict kong_rate_limiting_counters 12m;
3738
> if database == "cassandra" then
3839
lua_shared_dict kong_cassandra 5m;
3940
> end

spec/fixtures/custom_nginx.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ http {
4747
lua_shared_dict kong_process_events 5m;
4848
lua_shared_dict kong_cluster_events 5m;
4949
lua_shared_dict kong_healthchecks 5m;
50+
lua_shared_dict kong_rate_limiting_counters 12m;
5051
> if database == "cassandra" then
5152
lua_shared_dict kong_cassandra 5m;
5253
> end

0 commit comments

Comments
 (0)