Skip to content

Redis Cache setup example

Conor McKnight edited this page May 15, 2026 · 14 revisions

This example is to show how with Redis you can Cache the results grabbed from a redis server what will help performance especially servers in different locations. https://github.com/C0nw0nk/Nginx-Lua-Anti-DDoS/wiki/Redis-setup-example

With Redis Cache Example

Spoiler : rewrite_by_lua works with New Nginx Lua versions ONLY
#http block
#Initialize a shared Lua cache for Redis queries
lua_shared_dict RedisQueries 10m;
# you do not need the following line if you are using
# the OpenResty bundle:
# https://github.com/openresty/lua-resty-redis
lua_package_path "./conf/lua/lua-resty-redis/lib/?.lua;;";

lua_shared_dict antiddos 70m; #Anti-DDoS shared memory zone to track requests per each unique user
lua_shared_dict antiddos_blocked 70m; #Anti-DDoS shared memory where blocked users are put
lua_shared_dict ddos_counter 10m; #Anti-DDoS shared memory zone to track total number of blocked users
lua_shared_dict jspuzzle_tracker 70m; #Anti-DDoS shared memory zone monitors each unique ip and number of times they stack up failing to solve the puzzle
access_by_lua_file conf/lua/anti_ddos_challenge.lua;

server {

	location /test {

		# need to specify the resolver to resolve the hostname
		resolver 8.8.8.8;

		#open rewrite by lua tag
		# for large configurations use
		#rewrite_by_lua_file custom_settings.lua #you can make your configurations as big as you like without hitting limits
		rewrite_by_lua_block {

			local Query = ngx.shared.RedisQueries
			if not res then
				res = nil
			end
			local QResult = Query:get(res) -- disable this line disables the cache
			if not QResult then

				local redis = require "resty.redis"
				local red = redis:new()

				red:set_timeouts(1000, 1000, 1000) -- 1 sec

				--or connect to a unix domain socket file listened
				--by a redis server:
				--local ok, err = red:connect("unix:/path/to/redis.sock")

				-- connect via ip address directly
				local ok, err = red:connect("127.0.0.1", 6379)

				if not ok then
					--ngx.say("failed to connect: ", err)
					return
				end

				if localized_global == nil then --if global not exists
					localized_global = {} --define global var that script can read
				end

				local ok, err = red:set("secret", " enigma")
				if not ok then
					--ngx.say("failed to set secret key: ", err)
					return
				end

				--ngx.say("set result: ", ok)

				res, err = red:get("secret") --res is a global var so cache can work
				if not res then
					--ngx.say("failed to get secret: ", err)
					return
				else
					--result found do something
					localized_global.secret = res --nginx will now set secret key via Redis Database
				end

				if res == ngx.null then
					--ngx.say("secret not found.")
					return
				end

				--ngx.say("secret key: ", res)

				-- put it into the connection pool of size 100,
				-- with 10 seconds max idle time
				local ok, err = red:set_keepalive(10000, 100)
				if not ok then
					--ngx.say("failed to set keepalive: ", err)
					return
				end

				--or just close the connection right away:
				--local ok, err = red:close()
				--if not ok then
				--	ngx.say("failed to close: ", err)
				--	return
				--end

			else
				localized_global = {} --define global var that script can read
				localized_global.secret = QResult --nginx will now set secret key via Cached Redis database result
			end

		} #end rewrite_by_lua_block

	} #end location block

} #end server block
Spoiler : set_by_lua works with All Old and New Nginx Lua versions
#http block
#Initialize a shared Lua cache for Redis queries
lua_shared_dict RedisQueries 10m;
# you do not need the following line if you are using
# the OpenResty bundle:
# https://github.com/openresty/lua-resty-redis
lua_package_path "./conf/lua/lua-resty-redis/lib/?.lua;;";

lua_shared_dict antiddos 70m; #Anti-DDoS shared memory zone to track requests per each unique user
lua_shared_dict antiddos_blocked 70m; #Anti-DDoS shared memory where blocked users are put
lua_shared_dict ddos_counter 10m; #Anti-DDoS shared memory zone to track total number of blocked users
lua_shared_dict jspuzzle_tracker 70m; #Anti-DDoS shared memory zone monitors each unique ip and number of times they stack up failing to solve the puzzle
access_by_lua_file conf/lua/anti_ddos_challenge.lua;

server {

	location /test {

		# need to specify the resolver to resolve the hostname
		resolver 8.8.8.8;

		#open set by lua tag
		# for large configurations use
		#set_by_lua_file $localized_global custom_settings.lua #you can make your configurations as big as you like without hitting limits
		set_by_lua $localized_global '

			local load = load
			local localized_global = [[

			local Query = ngx.shared.RedisQueries
			if not res then
				res = nil
			end
			local QResult = Query:get(res) -- disable this line disables the cache
			if not QResult then

				local redis = require "resty.redis"
				local red = redis:new()

				red:set_timeouts(1000, 1000, 1000) -- 1 sec

				--or connect to a unix domain socket file listened
				--by a redis server:
				--local ok, err = red:connect("unix:/path/to/redis.sock")

				-- connect via ip address directly
				local ok, err = red:connect("127.0.0.1", 6379)

				if not ok then
					--ngx.say("failed to connect: ", err)
					return
				end

				if localized_global == nil then --if global not exists
					localized_global = {} --define global var that script can read
				end

				local ok, err = red:set("secret", " enigma")
				if not ok then
					--ngx.say("failed to set secret key: ", err)
					return
				end

				--ngx.say("set result: ", ok)

				res, err = red:get("secret") --res is a global var so cache can work
				if not res then
					--ngx.say("failed to get secret: ", err)
					return
				else
					--result found do something
					localized_global.secret = res --nginx will now set secret key via Redis Database
				end

				if res == ngx.null then
					--ngx.say("secret not found.")
					return
				end

				--ngx.say("secret key: ", res)

				-- put it into the connection pool of size 100,
				-- with 10 seconds max idle time
				local ok, err = red:set_keepalive(10000, 100)
				if not ok then
					--ngx.say("failed to set keepalive: ", err)
					return
				end

				--or just close the connection right away:
				--local ok, err = red:close()
				--if not ok then
				--	ngx.say("failed to close: ", err)
				--	return
				--end

			else
				localized_global = {} --define global var that script can read
				localized_global.secret = QResult --nginx will now set secret key via Cached Redis database result
			end

			]]
			return load(localized_global,"=localized_global_rediscache1")() --loadstring to run lua code from our set ngx variable

		'; #end set_by_lua tag

	} #end location block

} #end server block

Clone this wiki locally