Skip to content

Commit b0ee864

Browse files
committed
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 1d16030 commit b0ee864

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
@@ -82,6 +82,7 @@ return {
8282
"kong_process_events",
8383
"kong_cluster_events",
8484
"kong_healthchecks",
85+
"kong_rate_limiting_counters",
8586
},
8687
DATABASE = {
8788
POSTGRES = {

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
@@ -33,6 +33,7 @@ lua_shared_dict kong_cache ${{MEM_CACHE_SIZE}};
3333
lua_shared_dict kong_process_events 5m;
3434
lua_shared_dict kong_cluster_events 5m;
3535
lua_shared_dict kong_healthchecks 5m;
36+
lua_shared_dict kong_rate_limiting_counters 12m;
3637
> if database == "cassandra" then
3738
lua_shared_dict kong_cassandra 5m;
3839
> end

spec/fixtures/custom_nginx.template

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

0 commit comments

Comments
 (0)