Stateful Application Server_JRubyConf13_Lukas Rieder

60

Click here to load reader

Transcript of Stateful Application Server_JRubyConf13_Lukas Rieder

Page 1: Stateful Application Server_JRubyConf13_Lukas Rieder

stateful application

server

Page 2: Stateful Application Server_JRubyConf13_Lukas Rieder

HiI’m Lukas

@Overbryd

Page 3: Stateful Application Server_JRubyConf13_Lukas Rieder

Working@Wooga

Page 4: Stateful Application Server_JRubyConf13_Lukas Rieder
Page 5: Stateful Application Server_JRubyConf13_Lukas Rieder

stateful application

server

Page 6: Stateful Application Server_JRubyConf13_Lukas Rieder

database based system

Page 7: Stateful Application Server_JRubyConf13_Lukas Rieder

app

app

app

load db

clients

Page 8: Stateful Application Server_JRubyConf13_Lukas Rieder

stateful system

Page 9: Stateful Application Server_JRubyConf13_Lukas Rieder

app

app

app

client

Page 10: Stateful Application Server_JRubyConf13_Lukas Rieder

app

app

app

dns load

clients

Page 11: Stateful Application Server_JRubyConf13_Lukas Rieder

every server is equal

Page 12: Stateful Application Server_JRubyConf13_Lukas Rieder

app

nginx jvm

redis ssd

Page 13: Stateful Application Server_JRubyConf13_Lukas Rieder

state

Page 14: Stateful Application Server_JRubyConf13_Lukas Rieder

jvm

{}

Page 15: Stateful Application Server_JRubyConf13_Lukas Rieder

‣ SessionManager‣ Session‣ Resources‣ Items‣ Quests‣ Payments

...

Page 16: Stateful Application Server_JRubyConf13_Lukas Rieder

the hard part

Page 17: Stateful Application Server_JRubyConf13_Lukas Rieder

one place at a time

Page 18: Stateful Application Server_JRubyConf13_Lukas Rieder

easy with one server,but how to scale out?

Page 19: Stateful Application Server_JRubyConf13_Lukas Rieder

sharding!

Page 20: Stateful Application Server_JRubyConf13_Lukas Rieder

“static sharding”

shard = facebook_id % shards

Page 21: Stateful Application Server_JRubyConf13_Lukas Rieder
Page 22: Stateful Application Server_JRubyConf13_Lukas Rieder

raise Invalid, “wrong shard” unless Shard.valid?(facebook_id)

Page 23: Stateful Application Server_JRubyConf13_Lukas Rieder

concurrency

Page 24: Stateful Application Server_JRubyConf13_Lukas Rieder

jvm

http threads

sessions

ticker thread

workerthreads

Page 25: Stateful Application Server_JRubyConf13_Lukas Rieder

the hard part

Page 26: Stateful Application Server_JRubyConf13_Lukas Rieder

serialized accessto a session

Page 27: Stateful Application Server_JRubyConf13_Lukas Rieder

easy for low contentionlike a single session

Page 28: Stateful Application Server_JRubyConf13_Lukas Rieder

class Session

attr_reader :lock

def initialize @lock = Mutex.new end

# ...end

session.lock.synchronize do session.fooend

Page 29: Stateful Application Server_JRubyConf13_Lukas Rieder

harder for high contentionlike the SessionManager

Page 30: Stateful Application Server_JRubyConf13_Lukas Rieder

class SessionManager

@current = ConcurrentHashMap.new

def self.get(id) raise WrongShard unless Shard.valid?(id) unless session = @current.get(id) new_session = create(id) unless session = @current.put_if_absent(id, new_session) session = new_session end end session end

end

Page 31: Stateful Application Server_JRubyConf13_Lukas Rieder

t1

t2

{}S

S

Page 32: Stateful Application Server_JRubyConf13_Lukas Rieder

t1

t2

{}S

S

Page 33: Stateful Application Server_JRubyConf13_Lukas Rieder

t1

t2

{}S

S

session = @current.get(id)# => nil

session = @current.get(id)# => nil

Page 34: Stateful Application Server_JRubyConf13_Lukas Rieder

S2

t1

t2

{}S

S

Page 35: Stateful Application Server_JRubyConf13_Lukas Rieder

S2

t1

t2

{}S

S

S1

S2

Page 36: Stateful Application Server_JRubyConf13_Lukas Rieder

S2

t1

t2

{}S

S

S1

S2

S2

Page 37: Stateful Application Server_JRubyConf13_Lukas Rieder

S2

t1

t2

{}S

S

S1

S2

S2

S2

Page 38: Stateful Application Server_JRubyConf13_Lukas Rieder

S2

t1

t2

{}S

S

S1

S2

S2

S2

Page 39: Stateful Application Server_JRubyConf13_Lukas Rieder

S2

new_session = create(id)unless session = @current.put_if_absent(id, new_session) # => nil session = new_session # => #<Session:0x2>end

t1

new_session = create(id)unless session = @current.put_if_absent(id, new_session)# => #<Session:0x2>

t2

{}S

S

S1

S2

S2

S2

Page 40: Stateful Application Server_JRubyConf13_Lukas Rieder

deployment

Page 41: Stateful Application Server_JRubyConf13_Lukas Rieder

the hard part

Page 42: Stateful Application Server_JRubyConf13_Lukas Rieder

one place at a time

Page 43: Stateful Application Server_JRubyConf13_Lukas Rieder

handover

Page 44: Stateful Application Server_JRubyConf13_Lukas Rieder

app

nginx jvm1

jvm2

S1

Page 45: Stateful Application Server_JRubyConf13_Lukas Rieder

app

nginx jvm1

jvm2

S1

Page 46: Stateful Application Server_JRubyConf13_Lukas Rieder

app

nginx jvm1

jvm2S1

Page 47: Stateful Application Server_JRubyConf13_Lukas Rieder

app

nginx

jvm2S1

Page 48: Stateful Application Server_JRubyConf13_Lukas Rieder

global state

Page 49: Stateful Application Server_JRubyConf13_Lukas Rieder

weird problemwhen handling sharded state

Page 50: Stateful Application Server_JRubyConf13_Lukas Rieder

even weirder whenevery machine should be equal

Page 51: Stateful Application Server_JRubyConf13_Lukas Rieder

app

nginx jvm

redis ssd

Page 52: Stateful Application Server_JRubyConf13_Lukas Rieder

global data is kept local

Page 53: Stateful Application Server_JRubyConf13_Lukas Rieder

populates via UPD broadcast

Page 54: Stateful Application Server_JRubyConf13_Lukas Rieder

not “a huge” problem if stale

Page 55: Stateful Application Server_JRubyConf13_Lukas Rieder

last write winsself healing

Page 56: Stateful Application Server_JRubyConf13_Lukas Rieder

class Broadcast

def self.spawn_listener Thread.new do socket = wait_until_socket_bind loop do if @stop_listener socket.close return end message, from = socket.recvfrom(1024) handle_message(message) end end end

end

Page 57: Stateful Application Server_JRubyConf13_Lukas Rieder

appjvm redis appjvm redis

internal network

jvm

Page 58: Stateful Application Server_JRubyConf13_Lukas Rieder

appjvm redis appjvm redis

internal network

jvm

Page 59: Stateful Application Server_JRubyConf13_Lukas Rieder

appjvm redis appjvm redis

internal network

jvm

Page 60: Stateful Application Server_JRubyConf13_Lukas Rieder