SlideShare a Scribd company logo
1 of 143
Download to read offline
O que aprendi após 3 bilhões
de jobs processados no Sidekiq
Anderson Dias
@extendsmymind
https://medium.com/@extendsmymind
onde trabalho
Carlos Brando

CTO no Enjoei :P
Daniel Romero

ex-devops no Enjoei :P
biblioteca de processamento
assíncrono em ruby
revisão rápida
como funciona o sidekiq?
class ImagesController < ApplicationController
def create
@image = Image.create(params[:image])
@image.process
end
end
operação síncrona bloqueante
class ImagesController < ApplicationController
def create
@image = Image.create(params[:image])
ImageProcessor.perform_async(@image.id)
end
end
operação assíncrona não bloqueante
anatomia de um worker
class ImageProcessor
include Sidekiq::Worker
sidekiq_options queue: 'low', retry: true
def perform(image_id)
image = Image.find(image_id)
image.process
end
end
workers
class ImageProcessor
include Sidekiq::Worker
sidekiq_options queue: 'low', retry: true
def perform(image_id)
image = Image.find(image_id)
image.process
end
end
configurações do worker
class ImageProcessor
include Sidekiq::Worker
sidekiq_options queue: 'low', retry: true
def perform(image_id)
image = Image.find(image_id)
image.process
end
end
parâmetros do worker
invocando jobs
ImageProcessor.perform_async(1)
ImageProcessor.perform_in(5.minutes, 1)
ImageProcessor.perform_at(5.minutes.from_now, 1)
ImageProcessor.set(queue: :critical).perform_async(1)
Sidekiq::Client.push('class' => ImageProcessor, 'args' => [1])
diversas formas de executar um job
executando o sidekiq
diversas formas de executar
sidekiq # executa com a configuração padrão
sidekiq -c 25 # 25 de concorrência
sidekiq -q default -q high # executa duas filas
monitoramento
os erros mais comuns

que cometi
os erros mais comuns

que cometi
idiotas
Dica #1:

não seja enganado pelos

seus testes unitários
class NamedParamsWorker
include Sidekiq::Worker
def perform(a: , b: )
...
end
end
RSpec.describe NamedParamsWorker do
describe '#perform' do
it 'prints information' do
subject.perform(a: 1, b: 1)
end
end
end
seus testes unitários podem te enganar
class HashParamsWorker
include Sidekiq::Worker
def perform(params)
logger.info params[:a]
end
end
RSpec.describe HashParamsWorker do
describe '#perform' do
it 'prints information' do
subject.perform(a: 1, b: 1)
end
end
end
RSpec.describe NamedParamsWorker do
describe '#perform' do
it 'prints information' do
subject.perform(a: 1, b: 1)
end
end
end
RSpec.describe HashParamsWorker do
describe '#perform' do
it 'prints information' do
subject.perform(a: 1, b: 1)
end
end
end
seus testes unitários podem te enganar
require 'sidekiq/testing'
RSpec.describe NamedParamsWorker do
describe '#perform' do
it 'prints information' do
Sidekiq::Testing.inline! do
described_class.perform_async(a: 1, b: 1)
end
end
end
end
teste utilizando chamada inline, funciona?
RSpec.describe HashParamsWorker do
describe '#perform' do
it 'prints information' do
described_class.perform_async(a: 1, b: 1)
described_class.drain
end
end
end
utilize o .drain para simular as chamadas

reais à API do Sidekiq
Dica #2:

sempre faça parsing de datas
class ReportWorker
include Sidekiq::Worker
def perform(until_date)
objects = Model.where('created_at <= ?', until_date)
end
end
# Fri, 20 Oct 2017 19:00:00 BRST -02:00
ReportWorker.perform_async(1.day.ago)
o que acontece se:
SELECT "models".*
FROM "models"
WHERE (created_at <= '2017-10-20 19:00:00 -0200')
tudo ok, não?
SELECT "models".*
FROM "models"
WHERE (created_at <= '2017-10-20 19:00:00 -0200')
não, o filtro pela data está errado.
class ReportWorker
include Sidekiq::Worker
def perform(until_date)
parsed_time = Time.zone.parse(until_date)
objects = Model.where('created_at <= ?', parsed_time)
end
end
sempre que receber uma data,

faça parse dela no timezone atual
SELECT "models".*
FROM "models"
WHERE (created_at <= '2017-10-20 21:00:00.000000')
data passada com timezone correto
Dica #3:

nunca confie que o job vai ser
executado imediatamente
salvando histórico de intenções de compra
class PurchasesController < ApplicationController
def new
@product = Product.find(params[:product_id])
StorePurchaseIntentWorker.perform_async(current_user.id,
@product.id)
end
end
salvando histórico de intenções de compra
class StorePurchaseIntentWorker
include Sidekiq::Worker
def perform(user_id, product_id)
PurchaseIntent.create(user_id: user_id,
product_id: product_id)
end
end
salvando histórico de intenções de compra
class StorePurchaseIntentWorker
include Sidekiq::Worker
def perform(user_id, product_id)
PurchaseIntent.create(user_id: user_id,
product_id: product_id)
end
end
salvando histórico de intenções de compra
class StorePurchaseIntentWorker
include Sidekiq::Worker
def perform(user_id, product_id, created_at)
PurchaseIntent.create(
user_id: user_id,
product_id: product_id,
created_at: Time.zone.parse(created_at)
)
end
end
Dica #4:
sempre criptografe

dados sensíveis
processando compras com cartão de crédito
class CreditCardPurchaseWorker
include Sidekiq::Worker
def perform(purchase_id, number, name, expiration_date, cvc)
...
end
end
é possível visualizar os dados via sidekiq/web
credit_card_params = {
number: '4444333322221111', name: 'Joao Silva',
expiration_date: ’10/20', cvc: '123'
}
json_credit_card_params = credit_card_params.to_json
SecureCreditCardPurchaseWorker.perform_async(
14151,
json_credit_card_params.encrypt(
:symmetric,
password: ENV['SECRET_KEY_BASE']
)
)
criptografando os dados do cartão
decriptografando os dados do cartão
class SecureCreditCardPurchaseWorker
include Sidekiq::Worker
def perform(purchase_id, cryptographed_credit_card)
@cryptographed_credit_card = cryptographed_credit_card
credit_card_information = JSON.parse(decrypted_credit_card)
puts credit_card_information['number']
end
private
def decrypted_credit_card
@cryptographed_credit_card.decrypt(
:symmetric,
password: ENV['SECRET_KEY_BASE']
)
end
end
dados ilegíveis no sidekiq/web
Dica #5:
evite ao máximo utilizar delay
delay era bem comum antes do Sidekiq 5
UserMailer.delay.welcome_email(@user.id)
User.delay_until(2.weeks.from_now).whatever
@product.delay.destroy
porém no Sidekiq 5…
Delayed Extensions
desativadas por padrão.
nós bagunçamos a parada :P
o grande problema
UserMailer.delay.welcome_email(@user.id)
User.delay_until(2.weeks.from_now).whatever
@product.delay.destroy
usando da forma correta
utilizando da forma errada
a regra é
# Ao invés de:
@product.delay.destroy
# Prefira:
Product.delay.destroy(@product.id)
ProductDestroyerWorker.perform_async(@product.id)
Dica #6:
muito cuidado com os logs
Sidekiq é extremamente verboso
crie uma forma fácil de ativar/desativar

logs através de ENV vars
# config/initializers/sidekiq.rb
if (ENV["SIDEKIQ_LOGS_DISABLED"] == "true")
Sidekiq::Logging.logger = nil
end
dicas para o sidekiq pro
Sidekiq Batch
o que são batches
batch = Sidekiq::Batch.new
batch.jobs do
FirstWorker.perform_async

SecondWorker.perform_async
end
Dica #7:
cuidado com iterações, pois
batches são atômicos
qual o erro aqui?
batch = Sidekiq::Batch.new
products.find_each do |product|
batch.jobs { ProductWorker.perform_async(product.id) }
end
agende todos os jobs dentro

de uma única chamada de batch.jobs
batch = Sidekiq::Batch.new
batch.jobs do
products.find_each do |product|
ProductWorker.perform_async(product.id)
end
end
Dica #8:
cuidado com jobs únicos
dentro de batches
o que acontece?
batch = Sidekiq::Batch.new
batch.jobs do
UniqueWorker.perform_async(1)
raise
end
batch = Sidekiq::Batch.new
batch.jobs do
UniqueWorker.perform_async(1)
UniqueWorker.perform_async(2)
end
não, o sidekiq só processou 1 job do batch
https://github.com/mperham/sidekiq/issues/3662
Dica #9:
cuidado ao utilizar operações
destrutivas em batches
qual o problema aqui?
class EnqueueInvitationEmailWorker
include Sidekiq::Worker
def perform
batch = Sidekiq::Batch.new
batch.jobs do
while attributes = EmailSerializer.pop
SendInvitationEmailWorker.perform_async(attributes)
end
end
end
end
nesse caso é melhor não utilizar batch
class EnqueueInvitationEmailWorker
include Sidekiq::Worker
def perform
while attributes = EmailSerializer.pop
SendInvitationEmailWorker.perform_async(attributes)
end
end
end
dicas para o sidekiq
enterprise
Dica #10:
criptografe dados sensíveis

(versão enterprise)
criptografando parâmetros manualmente
require 'encrypted_strings'
require 'json'
credit_card_params = {}.to_json
encrypted_params = credit_card_params.encrypt(:symmetric, password: ENV['SECRET_KEY_BASE'])
SecureCreditCardPurchaseWorker.perform_async(12, encrypted_params)
class SecureCreditCardPurchaseWorker
include Sidekiq::Worker
def perform(purchase_id, cryptographed_credit_card)
credit_card_information = decrypted_credit_card(cryptographed_credit_card)
end
def decrypted_credit_card(cryptographed_credit_card)
JSON.parse(cryptographed_credit_card.decrypt(:symmetric, password: ENV['SECRET_KEY_BASE']))
end
end
configurando a extensão ent encryption
# config/initializers/sidekiq.rb
version = ENV.fetch('SIDEKIQ_CRYPTO_VERSION')
Sidekiq::Enterprise::Crypto.enable(active_version: version) do |version|
Base64.decode64(ENV.fetch("SIDEKIQ_CRYPTO_KEY_V#{version}"))
end unless Rails.env.test?
# .env
SIDEKIQ_CRYPTO_VERSION=2
SIDEKIQ_CRYPTO_KEY_V1=XXXXXXXX
SIDEKIQ_CRYPTO_KEY_V2=YYYYYYYY
utilizando ent encryption em um worker
class SecureCreditCardPurchaseWorker
include Sidekiq::Worker
sidekiq_options encrypt: true
def perform(purchase_id, cryptographed_credit_card)
puts cryptographed_credit_card['number']
end
end
credit_card_params = {
number: '4444333322221111', name: 'Joao Silva',
expiration_date: '10/20', cvc: '123'
}
SecureCreditCardPurchaseWorker.perform_async(12341, credit_card_params)
utilizando ent encryption em um worker
mais exemplos: somente o último

parâmetro será criptografado
escalando o sidekiq
organização de queues
PaymentProcessorWorker

queue: default
ImageProcessorWorker

queue: default
SalesReportWorker

queue: default
Rápido e crítico Lento e não crítico Lento, pesado e não crítico
sidekiq -c 10 -q default
10 50 1
múltiplos workers em fila única
Pros Contras
Fácil manutenção
Processos críticos podem
demorar muito a processar
quando houverem muitos jobs
de baixa prioridade
PaymentProcessorWorker

queue: critical
ImageProcessorWorker

queue: default
SalesReportWorker

queue: low
Rápido e crítico Lento e não crítico Lento, pesado e não crítico
sidekiq -c 10 -q critical -q default -q low
10 50 1
múltiplas filas priorizadas
Pros Contras
Divisão clara de processos por
níveis de prioridade.
Existe risco de acúmulo de jobs
nas filas de menor prioridade se
houver alto volume de jobs nas
filas mais priorizadas.
PaymentProcessorWorker

queue: critical
ImageProcessorWorker

queue: default
SalesReportWorker

queue: low
Rápido e crítico Lento e não crítico Lento, pesado e não crítico
sidekiq -c 10 -q critical,4 -q default,2 -q low,1
10 50 1
múltiplas filas com pesos diferentes
Pros Contras
Com um único processo do
sidekiq você tem priorização
sem que as filas fiquem
esperando umas as outras.
Processos pesados ainda
podem interferir diretamente na
performance de processos
críticos.
PaymentProcessorWorker

queue: critical
ImageProcessorWorker

queue: default
SalesReportWorker

queue: low
Rápido e crítico Lento e não crítico Lento, pesado e não crítico
sidekiq -c 10 -q critical
10 50 1
processos isolados para cada queue
Pros Contras
Isolamento completo de cada fila
Controle de escala de cada
queue individual
Sonho?
Maior consumo de memória/
máquina
sidekiq -c 10 -q default sidekiq -c 2 -q low
de repente…
1. monitore o uso do sidekiq
2. isole processos críticos
3. identifique timeframes das
queues
4. reduza o número de filas
Dica #11:
monitore o uso do sidekiq
monitorando as filas
monitorando o tamanho das filas
Sidekiq::Queue.all.each do |queue|
Enjoei::Metrics.event(
'SidekiqQueueReport', name: queue.name, size: queue.size
)
end
monitorando processos online
queues_processing = Sidekiq::ProcessSet.new.map do |p|
p['queues'].flatten
end.uniq
queues_processing.each do |queue|
Enjoei::Metrics.event(
'SidekiqOnlineQueueReport', name: queue
)
end
Dica #12:
isole processos críticos
PaymentProcessorWorker

queue: critical
ImageProcessorWorker

queue: default
SalesReportWorker

queue: low
Rápido e crítico Lento e não crítico Lento, pesado e não crítico
sidekiq -c 10 -q critical
10 50 1
processos separados por criticidade
Pros Contras
Isolamento completo de filas
mais críticas
Permite escalar filas de forma
diferente
Maior consumo de memória/
máquina
sidekiq -c 10 -q default,2 -q low,1
Dica #13:
identifique timeframes
processos rodando em timeframes idênticos
processos rodando em timeframes diferentes
Dica #14:
reduza o número de filas e
processos
unifique filas que rodam em
timeframes diferentes
processos rodando em timeframes diferentes
unifique todos os processos em uma só fila
# Antes:
sidekiq -q invoice -c 3
sidekiq -q coupon_reminder_emails -c 10
sidekiq -q counter_cache_update -c 10
# Depois:
sidekiq -q low -c 10
substitua concorrência por
limiters em caso de rate limit
processo com concorrência por causa

de rate limit da API de terceiro
# Antes:
sidekiq -q invoice -c 3
sidekiq -q coupon_reminder_emails -c 10
sidekiq -q counter_cache_update -c 10
# Depois:
sidekiq -q low -c 10
utilize limiters
class InvoiceWorker
include Sidekiq::Worker
ERP_THROTTLE = Sidekiq::Limiter.concurrent('erp', 3)
def perform
ERP_THROTTLE.within_limit do
end
end
end
lidando com ociosidade e
concorrência em processos
com características comuns
período de ociosidade vs concorrência
ociosidade concorrência leve concorrência pesada
proposta 1:

unificar processos em fila única
# Antes:
sidekiq -q read_only_default -c 10
sidekiq -q read_only_low -c 10
sidekiq -q read_only_high -c 10
# Depois:
sidekiq -q read_only -c 10
Pros Contras
Única fila para gerenciar
Para escalar basta subir um
novo processo
Não existe prioridade de
execução
Em momento de concorrência
irá somar o tempo de execução
proposta 2:

unificar filas por prioridade
# Antes:
sidekiq -q read_only_default -c 10
sidekiq -q read_only_low -c 10
sidekiq -q read_only_high -c 10
# Depois:
sidekiq -q read_only_high 

-q read_only_default 
-q read_only_low -c 10
Pros Contras
Prioridade na execução
Só executará processos com menos
prioridade quando acabarem os
prioritários
Em momento de concorrência irá somar
o tempo de execução
proposta 3:

unificar filas por peso
# Antes:
sidekiq -q read_only_default -c 10
sidekiq -q read_only_low -c 10
sidekiq -q read_only_high -c 10
# Depois:
sidekiq -q read_only_high,4 

-q read_only_default,2 
-q read_only_low,1 -c 10
Pros Contras
Para escalar basta subir um novo
processo
Irá processar simultaneamente todas
as filas com prioridades diferentes
Em momento de concorrência
irá somar o tempo de execução
proposta 4:

fila única e utilizar autoscale
# Antes:
sidekiq -q read_only_default -c 10
sidekiq -q read_only_low -c 10
sidekiq -q read_only_high -c 10
# Depois:
sidekiq -q read_only -c 10
Pros Contras
Única fila para gerenciar
Auto scaling vai aumentar número
de processos para dar vazão a
todas as filas quando houver picos
Sem um limite para auto scaling você
pode acabar consumindo muitos
recursos e derrubar sua base de dados
Pode demorar mais para processar os
jobs em momentos de picos
recursos sobre auto scaling
https://engenharia.elo7.com.br/sidekiq-workers/

http://www.pablocantero.com/blog/2013/05/04/auto-scale-sidekiq-workers-on-amazon-ec2/
http://manuelvanrijn.nl/blog/2012/11/13/scalable-heroku-worker-for-sidekiq/



http://blog.honeybadger.io/cleanly-scaling-sidekiq/
o pior pesadelo
informação do job é totalmente perdida
antes
depois
Dica #15:
cuidado ao iterar sobre

longos arrays
https://github.com/mperham/sidekiq/wiki/Problems-and-Troubleshooting
https://github.com/mperham/sidekiq/wiki/Problems-and-Troubleshooting
“Unfortunately it's up to you to
determine which worker and query
is causing the [memory] bloat.”
Mike Perham
Sidekiq creator
“Unfortunately it's up to you to
determine which worker and query
is causing the [memory] bloat.”
Mike Perham
Sidekiq creator
👍
pensando fora da caixa
Dica #16:
utilize processos separados para
ler de bases readonly
sidekiq -q default
workers por tipo de acesso aos dados
PaymentProcessorWorker

queue: default
ImageProcessorWorker

queue: default
SalesReportWorker

queue: readonly
SalesMailer.completed

queue: readonly
master
DATABASE_URL=$FOLLOWER_DATABASE_URL

sidekiq -q readonly
follower
replicação de dados
envie emails em filas readonly
config/initializers/sidekiq.rb
Sidekiq::Extensions.enable_delay!
# require DelayedMailer class in order to bypass lazy load
require 'sidekiq/extensions/action_mailer'
Sidekiq::Extensions::DelayedMailer.sidekiq_options queue: :readonly
em bases readonly sempre conte
com o delay de sincronização
replicação de base pode ter delay
master follower
replicação de dados
o que ocorre quando buscamos o produto?
class ProductMailer < ApplicationMailer
def published(product_id)
@product = Product.find(product_id)
...
end
end
class Product < ActiveRecord::Base
after_create do |product|
ProductMailer.delay.published(product.id)
end
end
cuidado com os callbacks do
ActiveRecord::Base
class ProductMailer < ApplicationMailer
def published(product_id)
@product = Product.find(product_id)
...
end
end
class Product < ActiveRecord::Base
after_create do |product|
ProductMailer.delay.published(product.id)
end
end
adicione um pequeno delay em

jobs que usam base follower
class ProductMailer < ApplicationMailer
def published(product_id)
@product = Product.find(product_id)
...
end
end
class Product < ActiveRecord::Base
after_create_commit do |product|
ProductMailer.delay_for(10.seconds).published(product.id)
end
end
sempre utilize callbacks de commit
class ProductMailer < ApplicationMailer
def published(product_id)
@product = Product.find(product_id)
...
end
end
class Product < ActiveRecord::Base
after_create_commit do |product|
ProductMailer.delay_for(10.seconds).published(product.id)
end
end
Dica #17:
utilize sidekiq para comunicar entre
diferentes sistemas/tecnologias
https://github.com/andersondias/multiplatform-sidekiq
RubyApp::Workers::ProducerWorker

queue: ruby
ruby_app: sidekiq -q ruby
CrystalApp::Workers::ReceiverWorker

queue: crystal
crystal_app: sidekiq -q crystal
Toda a comunicação entre as
aplicações é feita através de
escritas em filas.
comunicando através de filas
RubyApp::Workers::ProducerWorker

queue: ruby
ruby_app: sidekiq -q ruby
CrystalApp::Workers::ReceiverWorker

queue: crystal
crystal_app: sidekiq -q crystal
escrevendo jobs em outra aplicação
job = Sidekiq::Job.new
job.klass =
"RubyApp::Workers::ProducerWorker"
job.queue = "ruby"
Sidekiq::Client.new.push(job)
Sidekiq::Client.push(
'class' =>
'CrystalApp::Workers::ReceiverWorker',
'args' => [rand(10)],
'queue' => 'crystal'
)
Dica #18:
utilize outras tecnologias
métricas do enjuads
numa stack padrão
problema #1:

muitos dados passando pelo sidekiq
problema #2:

alto índice de insert/update no postgres
nossa solução usando stack da AWS
Kinesis Lambda DynamoDB
nossa solução usando stack da AWS
Substitui a queue

do Sidekiq com
baixa latência.
Substitui os workers e
agrupa “jobs”
automaticamente.
Substitui a base.
Faktory
https://github.com/contribsys/faktory
servidor faktory
conclusão

More Related Content

What's hot

Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018Araf Karsh Hamid
 
A Step By Step Guide To Put DB2 On Amazon Cloud
A Step By Step Guide To Put DB2 On Amazon CloudA Step By Step Guide To Put DB2 On Amazon Cloud
A Step By Step Guide To Put DB2 On Amazon CloudDeepak Rao
 
Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...
Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...
Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...Kai Wähner
 
Isv cloud business readiness assessment
Isv cloud business readiness assessmentIsv cloud business readiness assessment
Isv cloud business readiness assessmentMIS
 
OneStream Deep Dive
OneStream Deep DiveOneStream Deep Dive
OneStream Deep DiveFinext
 
The Ideal Approach to Application Modernization; Which Way to the Cloud?
The Ideal Approach to Application Modernization; Which Way to the Cloud?The Ideal Approach to Application Modernization; Which Way to the Cloud?
The Ideal Approach to Application Modernization; Which Way to the Cloud?Codit
 
Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...
Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...
Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...Amazon Web Services
 
Micro services Architecture
Micro services ArchitectureMicro services Architecture
Micro services ArchitectureAraf Karsh Hamid
 
Introduction to Amazon Kinesis Firehose - AWS August Webinar Series
Introduction to Amazon Kinesis Firehose - AWS August Webinar SeriesIntroduction to Amazon Kinesis Firehose - AWS August Webinar Series
Introduction to Amazon Kinesis Firehose - AWS August Webinar SeriesAmazon Web Services
 
An Overview of Best Practices for Large Scale Migrations - AWS Transformation...
An Overview of Best Practices for Large Scale Migrations - AWS Transformation...An Overview of Best Practices for Large Scale Migrations - AWS Transformation...
An Overview of Best Practices for Large Scale Migrations - AWS Transformation...Amazon Web Services
 
[AWS Migration Workshop] 데이터센터의 SAP를 AWS로 마이그레이션 하기
[AWS Migration Workshop]  데이터센터의 SAP를 AWS로 마이그레이션 하기[AWS Migration Workshop]  데이터센터의 SAP를 AWS로 마이그레이션 하기
[AWS Migration Workshop] 데이터센터의 SAP를 AWS로 마이그레이션 하기Amazon Web Services Korea
 
Chart of Accounts Transformation Master Class
Chart of Accounts Transformation Master ClassChart of Accounts Transformation Master Class
Chart of Accounts Transformation Master Classeprentise
 
Service Discovery with Consul
Service Discovery with ConsulService Discovery with Consul
Service Discovery with ConsulAli Demirsoy
 
Tackle Your Dark Data Challenge with AWS Glue - AWS Online Tech Talks
Tackle Your Dark Data  Challenge with AWS Glue - AWS Online Tech TalksTackle Your Dark Data  Challenge with AWS Glue - AWS Online Tech Talks
Tackle Your Dark Data Challenge with AWS Glue - AWS Online Tech TalksAmazon Web Services
 
Confluent Cloud Networking | Rajan Sundaram, Confluent
Confluent Cloud Networking | Rajan Sundaram, ConfluentConfluent Cloud Networking | Rajan Sundaram, Confluent
Confluent Cloud Networking | Rajan Sundaram, ConfluentHostedbyConfluent
 

What's hot (20)

Core Banking System on Apache Kafka
Core Banking System on Apache KafkaCore Banking System on Apache Kafka
Core Banking System on Apache Kafka
 
Amazon Kinesis
Amazon KinesisAmazon Kinesis
Amazon Kinesis
 
Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018
 
A Step By Step Guide To Put DB2 On Amazon Cloud
A Step By Step Guide To Put DB2 On Amazon CloudA Step By Step Guide To Put DB2 On Amazon Cloud
A Step By Step Guide To Put DB2 On Amazon Cloud
 
Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...
Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...
Apache Kafka in Gaming Industry (Games, Mobile, Betting, Gambling, Bookmaker,...
 
Isv cloud business readiness assessment
Isv cloud business readiness assessmentIsv cloud business readiness assessment
Isv cloud business readiness assessment
 
OneStream Deep Dive
OneStream Deep DiveOneStream Deep Dive
OneStream Deep Dive
 
The Ideal Approach to Application Modernization; Which Way to the Cloud?
The Ideal Approach to Application Modernization; Which Way to the Cloud?The Ideal Approach to Application Modernization; Which Way to the Cloud?
The Ideal Approach to Application Modernization; Which Way to the Cloud?
 
Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...
Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...
Cost Optimizing Your Architecture: Practical Design Steps for Developer Savin...
 
Elastic-Engineering
Elastic-EngineeringElastic-Engineering
Elastic-Engineering
 
Micro services Architecture
Micro services ArchitectureMicro services Architecture
Micro services Architecture
 
Introduction to Amazon Kinesis Firehose - AWS August Webinar Series
Introduction to Amazon Kinesis Firehose - AWS August Webinar SeriesIntroduction to Amazon Kinesis Firehose - AWS August Webinar Series
Introduction to Amazon Kinesis Firehose - AWS August Webinar Series
 
An Overview of Best Practices for Large Scale Migrations - AWS Transformation...
An Overview of Best Practices for Large Scale Migrations - AWS Transformation...An Overview of Best Practices for Large Scale Migrations - AWS Transformation...
An Overview of Best Practices for Large Scale Migrations - AWS Transformation...
 
How to analyzing sap critical authorizations
How to analyzing sap critical authorizationsHow to analyzing sap critical authorizations
How to analyzing sap critical authorizations
 
[AWS Migration Workshop] 데이터센터의 SAP를 AWS로 마이그레이션 하기
[AWS Migration Workshop]  데이터센터의 SAP를 AWS로 마이그레이션 하기[AWS Migration Workshop]  데이터센터의 SAP를 AWS로 마이그레이션 하기
[AWS Migration Workshop] 데이터센터의 SAP를 AWS로 마이그레이션 하기
 
Chart of Accounts Transformation Master Class
Chart of Accounts Transformation Master ClassChart of Accounts Transformation Master Class
Chart of Accounts Transformation Master Class
 
Brd template
Brd template Brd template
Brd template
 
Service Discovery with Consul
Service Discovery with ConsulService Discovery with Consul
Service Discovery with Consul
 
Tackle Your Dark Data Challenge with AWS Glue - AWS Online Tech Talks
Tackle Your Dark Data  Challenge with AWS Glue - AWS Online Tech TalksTackle Your Dark Data  Challenge with AWS Glue - AWS Online Tech Talks
Tackle Your Dark Data Challenge with AWS Glue - AWS Online Tech Talks
 
Confluent Cloud Networking | Rajan Sundaram, Confluent
Confluent Cloud Networking | Rajan Sundaram, ConfluentConfluent Cloud Networking | Rajan Sundaram, Confluent
Confluent Cloud Networking | Rajan Sundaram, Confluent
 

Similar to 3BilhõesJobsSidekiq

Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010lucashungaro
 
Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Railstchandy
 
Como ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComo ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComunidade NetPonto
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpecNando Vieira
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 
iOS Delegates - Mobile Conf Rio 2014
iOS Delegates - Mobile Conf Rio 2014iOS Delegates - Mobile Conf Rio 2014
iOS Delegates - Mobile Conf Rio 2014osnipso
 
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeIgor Nicoli
 
Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Rafael Ponte
 
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Carlos Duarte do Nascimento
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineCampus Party Brasil
 
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)Wennder Santos
 
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSFOs 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSFtarsobessa
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidNelson Glauber Leal
 
Desenvolvendo com Angular CLI
Desenvolvendo com Angular CLIDesenvolvendo com Angular CLI
Desenvolvendo com Angular CLIVanessa Me Tonini
 

Similar to 3BilhõesJobsSidekiq (20)

Rails na prática
Rails na práticaRails na prática
Rails na prática
 
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
 
Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Rails
 
Como ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComo ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noite
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpec
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
iOS Delegates - Mobile Conf Rio 2014
iOS Delegates - Mobile Conf Rio 2014iOS Delegates - Mobile Conf Rio 2014
iOS Delegates - Mobile Conf Rio 2014
 
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
 
Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)
 
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App Engine
 
Tornado
TornadoTornado
Tornado
 
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
 
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSFOs 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSF
 
React js
React js React js
React js
 
Aplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com DjangoAplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com Django
 
Node.js: serious business
Node.js: serious businessNode.js: serious business
Node.js: serious business
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
 
Desenvolvendo com Angular CLI
Desenvolvendo com Angular CLIDesenvolvendo com Angular CLI
Desenvolvendo com Angular CLI
 

3BilhõesJobsSidekiq