Scalin ling s servic ices w it it h Dis ist rib ibut ed In-Mem em ory Ca Caches
SATURN 201 8 | Plano, Texas Divya Nagar and Chirag Aggarw al
Scalin ling s servic ices w it it h Dis ist rib ibut ed In-Mem - - PowerPoint PPT Presentation
Scalin ling s servic ices w it it h Dis ist rib ibut ed In-Mem em ory Ca Caches SATURN 201 8 | Plano, Texas Divya Nagar and Chirag Aggarw al 900K+ Drivers 10 0 M+ Mon th ly Ord e rs 261M+ P e op le Im p acte d - 18+ P rod u cts -
SATURN 201 8 | Plano, Texas Divya Nagar and Chirag Aggarw al
900K+ Drivers 10 0 M+ Mon th ly Ord e rs 261M+ P e op le Im p acte d
sin ce first ap p lau n ch
Slick User Experience Low Re sp on se Tim e s Hig h Availab ility
Car Bike
Surge He at Map s
Acce p tab le Con siste n cy
Surge He at Map s
Diffe re n t Re q u ire m e n ts
github.com /gojekfarm /prattle
CA CACH CHE MEM EMBER ERSHIP RE REPLICA CATION
Mem bership
3 1 2 4 5 6 7 8
1 2 3 4 5 6
UDP Multicast
1 3 5 2 4 6
9 1 8 7 6 3 2 5 4
Quadratic Increase in Netw ork Congestion
1 3 5 2 4 6 6 is dead 4 is dead (1,2,3,5,6) (1,2,3,4,5)
False Positives
9 1 8 7 6 3 2 5 4 1 2 3 4 5 6 7 8
Reduce Netw ork Congestion
SW IM IS A
MEM EMBER ERSHIP PROT OTOC OCOL OL
func (m *Member) Ping(nodeAddress net.Addr) error { pingRequest := NewPingRequest{ NodeAddress: nodeAddress, } ackChannel := make(chan ackMessage, 1) defer close(ackChannel)
m.sendMessageUdp(&pingRequest, ackChannel) select { case ackMessage := <-ackChannel: logger.info(“ack message: + ackMessage) return nil case <-time.After(m.config.AckTimeout): return m.ProbeNode(nodeAddress) }
}
N1 N2
func (m *Member) Ping(nodeAddress net.Addr) error { pingRequest := NewPingRequest{ NodeAddress: nodeAddress, } ackChannel := make(chan ackMessage, 1) defer close(ackChannel)
m.sendMessageUdp(&pingRequest, ackChannel)
select { case ackMessage := <-ackChannel: logger.info(“ack message: + ackMessage) return nil case <-time.After(m.config.AckTimeout): return m.ProbeNode(nodeAddress) }
}
N1 N2
func (m *Member) Ping(nodeAddress net.Addr) error { pingRequest := NewPingRequest{NodeAddress: nodeAddress} ackChannel := make(chan ackMessage, 1) defer close(ackChannel) err := m.sendMessageUdp(nodeAddress.String(), &pingRequest, ackChannel) if err != nil { return err }
select { case ackMessage := <-ackChannel: logger.info(“ack message:” + ackMessage) return nil
case <-time.After(m.config.AckTimeout): return m.ProbeNode(nodeAddress) } }
N1 N2
func (m *Member) Ping(nodeAddress net.Addr) error { pingRequest := NewPingRequest{NodeAddress: nodeAddress} ackChannel := make(chan ackMessage, 1) defer close(ackChannel) err := m.sendMessageUdp(nodeAddress.String(), &pingRequest, ackChannel) if err != nil {
return err } select { case ackMessage := <-ackChannel:
logger.info(“ack message:” + ackMessage) return nil
case <-time.After(m.config.AckTimeout): return m.ProbeNode(nodeAddress) }
}
N1 N2
func (m *Member) ProbeNode(nodeAddress net.Addr) error { members := m.KRandomMembers() ackChannel := make(chan ackMessage, count(members))
for _, member := range members { pingRequest := NewPingRequest{NodeAddress: nodeAddress} member.sendMessageUdp(&pingRequest, ackChannel) } defer close(ackChannel) select { case ackMessage := <-ackChannel: logger.info(“ack message:” + ackMessage) return nil case <-time.After(m.config.AckTimeout): return errors.New(“timed out while probing”) }
}
N1 N2 N3
func (m *Member) ProbeNode(nodeAddress net.Addr) error { members := m.KRandomMembers() ackChannel := make(chan ackMessage, count(members))
for _, member := range members { pingRequest := NewPingRequest{ NodeAddress: nodeAddress, } member.sendMessageUdp(&pingRequest, ackChannel) } defer close(ackChannel)
select { case ackMessage := <-ackChannel: logger.info(“ack message:” + ackMessage) return nil case <-time.After(m.config.AckTimeout): return errors.New(“timed out while probing”) }
}
N1 N2 N3
N1 N2 N3
func (m *Member) ProbeNode(nodeAddress net.Addr) error { members := m.KRandomMembers() ackChannel := make(chan ackMessage, count(members)) for _, member := range members { pingRequest := NewPingRequest{ NodeAddress: nodeAddress, } member.sendMessageUdp(&pingRequest, ackChannel) } defer close(ackChannel)
select { case ackMessage := <-ackChannel: logger.info(“ack message:” + ackMessage) return nil
case <-time.After(m.config.AckTimeout): return errors.New(“timed out while probing”) } }
N1 N2 N3
func (m *Member) ProbeNode(nodeAddress net.Addr) error { members := m.KRandomMembers() ackChannel := make(chan ackMessage, count(members)) for _, member := range members { pingRequest := NewPingRequest{ NodeAddress: nodeAddress, } member.sendMessageUdp(&pingRequest, ackChannel) } defer close(ackChannel) select { case ackMessage := <-ackChannel: logger.info(“ack message:” + ackMessage) return nil
case <-time.After(m.config.AckTimeout): return errors.New(“timed out”) }
}
REPLIC ICATIO ION
1 2 3 4 5 6 7 8
Initial Im plem entation w ith Prattle
prattle := NewPrattle(siblingAddr string) prattle.SetViaGossip(key, value)
Problem s w ith Gossip Based Re p lication
1 2 3 4 5 6
UDP m ulticast based replication
prattle := NewPrattle(siblingAddr string) prattle.SetViaMulticast(key, value)