# install ruby with debug options with asdf
RUBY_CFLAGS=-O0 CONFIGURE_OPTS='cppflags=-DUSE_RUBY_DEBUG_LOG=1 --enable-debug-env optflags=-fno-omit-frame-pointer' asdf install ruby 3.3.2
Title: Mastering Redis Memory Management with Microserver and Sidekiq
Introduction: Microservers have become increasingly popular due to their flexibility and ease of deployment and testing. However, they also present challenges, particularly with memory management in services like Redis. In this article, we'll explore a real-world scenario where Redis memory usage spiked dramatically and the steps taken to regain control.
The Challenge: Redis Memory Surge Recently, I encountered a significant increase in Redis memory usage, jumping from 130MB to 800MB. Initially, I suspected the Redis cache was the culprit.
Redis Memory Inspection
Upon inspection with the INFO memory
command, the memory usage was as follows:
- Also known as the Global Interpreter Lock (GIL)
- A mutex that prevents multiple native threads from executing Ruby code in parallel
- Present in CRuby (the reference implementation of Ruby)
- Protects internal data structures from race conditions
- Ensures thread safety in the Ruby interpreter
In an ideal world, developers would be able to replicate all production problems locally, debug them, and roll out patches with the next release. However, real-life scenarios are often far more complex. Production environments present unique challenges that are difficult to replicate in development or even staging environments. This article explores various techniques for troubleshooting production issues, ranging from pre-production strategies to advanced debugging in live environments.
Several factors make production debugging particularly challenging:
IRB.conf[:PROMPT][:DEV] = { # name of prompt mode | |
:AUTO_INDENT => false, # disables auto-indent mode | |
:PROMPT_I => ">> ", # simple prompt | |
:PROMPT_S => nil, # prompt for continuated strings | |
:PROMPT_C => nil, # prompt for continuated statement | |
:RETURN => " ==>%s\n" # format to return value | |
} | |
#IRB.conf[:PROMPT_MODE] = :MY_PROMPT |
def check_queue(queues=[]) | |
if queues.empty? | |
queues = Sidekiq::Queue.all | |
else | |
queues = queues.map { |queue| Sidekiq::Queue.new(queue) } | |
end | |
queues.each do |queue| | |
queue.each do |job| |
require 'net/http' | |
module Net | |
class HTTP | |
def self.enable_debug! | |
class << self | |
alias_method :__new__, :new | |
def new(*args, &blk) | |
instance = __new__(*args, &blk) | |
instance.set_debug_output($stderr) | |
instance |
const { IncomingWebhook } = require('@slack/webhook'); | |
const url = process.env.SLACK_WEBHOOK_URL; | |
const webhook = new IncomingWebhook(url); | |
// Optionally filter what notification types to forward to Slack. | |
// If empty, all types will be allowed. | |
const allowedTypeURLs = []; | |
// slackNotifier is the main function called by Cloud Functions |