Реактивные микросервисы с apache kafka / Денис Иванов (2ГИС)

90
Реактивные микросервисы с Apache Kafka Денис Иванов [email protected] @denisivanov 1

Upload: ontico

Post on 21-Jan-2018

159 views

Category:

Engineering


1 download

TRANSCRIPT

Page 1: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Реактивные микросервисыс Apache Kafka

Денис Иванов[email protected]@denisivanov

1

Page 2: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Обо мне

2

Page 3: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Код и презентация

https://github.com/denisivan0v/highload-2017

3

Page 4: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

План

4

Page 5: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

5

Page 6: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Терминология

6

Page 7: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Терминология

7

Page 8: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Откуда берутся микросервисы?

8

Page 9: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Откуда берутся микросервисы?

Advertising Management System в

9

Page 10: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

10

Storage API

S3 Storage

High-level API

Frontend App

Откуда берутся микросервисы?

Page 11: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

11

Storage API

S3 Storage

High-level API

Frontend App

Откуда берутся микросервисы?

Page 12: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Challenges

•Синхронное/асинхронное взаимодействиекомпонентов

12

Page 13: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Challenges

•Синхронное/асинхронное взаимодействиекомпонентов•Гарантированная доставка данных с минимальными задержками

13

Page 14: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Challenges

•Синхронное/асинхронное взаимодействиекомпонентов•Гарантированная доставка данных с минимальными задержками•Распределенные изменения и согласованность

14

Page 15: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Challenges

•Синхронное/асинхронное взаимодействиекомпонентов•Гарантированная доставка данных с минимальными задержками•Распределенные изменения и согласованность

15

Page 16: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

Page 17: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

•Блокирующие•Неблокирующие (отложенные)

17

Page 18: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

18

Storage API

High-level API

S3 Storage

Page 19: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

19

Storage API

High-level API

S3 Storage

Page 20: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

20

Storage API

High-level API

S3 Storage

Page 21: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

21

Storage API

High-level API

S3 Storage

Page 22: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

22

Storage API

High-level API

S3 Storage

Page 23: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

23

Storage API

High-level API

S3 Storage

Page 24: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

24

/

Background workers

Frontend App

REST API

Storage

Фоновые процессы

/

Page 25: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

25

Page 26: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

26Kafka: The Definitive Guide by Neha Narkhede, Gwen Shapira, and Todd Palino (O’Reilly).

Распределенный лог

Page 27: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Kafka .NET Client

•Обертка над C-библиотекой librdkafka•Реализовано подмножество API (open source)•Использует managed и unmanaged память и потоки•xplat, .NET Core

27

Page 28: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Batched Kafka Consumer Wrapper

28

Page 29: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumer = new Consumer<Null, string>(config, new NullDeserializer(), new StringDeserializer(Encoding.UTF8));

29

Page 30: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumer = new Consumer<Null, string>(config, new NullDeserializer(), new StringDeserializer(Encoding.UTF8));

var messages = new List<Message<Null, string>>();var isEof = false;

30

Page 31: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumer = new Consumer<Null, string>(config, new NullDeserializer(), new StringDeserializer(Encoding.UTF8));

var messages = new List<Message<Null, string>>();var isEof = false;

void OnMessage(object sender, Message<Null, string> message) => messages.Add(message);

void OnEof(object sender, TopicPartitionOffset offset) => isEof = true;

31

Page 32: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumer = new Consumer<Null, string>(config, new NullDeserializer(), new StringDeserializer(Encoding.UTF8));

var messages = new List<Message<Null, string>>();var isEof = false;

void OnMessage(object sender, Message<Null, string> message) => messages.Add(message);

void OnEof(object sender, TopicPartitionOffset offset) => isEof = true;consumer.OnMessage += OnMessage;consumer.OnPartitionEOF += OnEof;consumer.Subscribe(topics);

32

Page 33: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumer = new Consumer<Null, string>(config, new NullDeserializer(), new StringDeserializer(Encoding.UTF8));

var messages = new List<Message<Null, string>>();var isEof = false;

void OnMessage(object sender, Message<Null, string> message) => messages.Add(message);

void OnEof(object sender, TopicPartitionOffset offset) => isEof = true;consumer.OnMessage += OnMessage;consumer.OnPartitionEOF += OnEof;consumer.Subscribe(topics);

while (messages.Count < batchSize && !isEof &&!cancellationToken.IsCancellationRequested)

{consumer.Poll(TimeSpan.FromMilliseconds(100));

}

33

Page 34: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumer = new Consumer<Null, string>(config, new NullDeserializer(), new StringDeserializer(Encoding.UTF8));

var messages = new List<Message<Null, string>>();var isEof = false;

void OnMessage(object sender, Message<Null, string> message) => messages.Add(message);

void OnEof(object sender, TopicPartitionOffset offset) => isEof = true;consumer.OnMessage += OnMessage;consumer.OnPartitionEOF += OnEof;consumer.Subscribe(topics);

while (messages.Count < batchSize && !isEof &&!cancellationToken.IsCancellationRequested)

{consumer.Poll(TimeSpan.FromMilliseconds(100));

}consumer.Unsubscribe(topics);

34

Page 35: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumerWrapper = new ConsumerWrapper(brokerEndpoints, groupId);

35

Page 36: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumerWrapper = new ConsumerWrapper(brokerEndpoints, groupId);while (!cancellationToken.IsCancellationRequested){

var messages = consumerWrapper.Consume(topics, batchSize, cancellationToken);

}

36

Page 37: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumerWrapper = new ConsumerWrapper(brokerEndpoints, groupId);while (!cancellationToken.IsCancellationRequested){

var messages = consumerWrapper.Consume(topics, batchSize, cancellationToken);

}

37

Page 38: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumerWrapper = new ConsumerWrapper(brokerEndpoints, groupId);while (!cancellationToken.IsCancellationRequested){

var messages = consumerWrapper.Consume(topics, batchSize, cancellationToken);

foreach (var message in messages){

Console.WriteLine($"{message.Topic}/{message.Partition} @" +$"{message.Offset}: '{message.Value}'");

}}

38

Page 39: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var consumerWrapper = new ConsumerWrapper(brokerEndpoints, groupId);while (!cancellationToken.IsCancellationRequested){

var messages = consumerWrapper.Consume(topics, batchSize, cancellationToken);

foreach (var message in messages){

Console.WriteLine($"{message.Topic}/{message.Partition} @" + $"{message.Offset}: '{message.Value}'");

await consumerWrapper.CommitAsync(message); }

}

Page 40: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

DEMO:Kafka + Docker + .NET Core

40

Page 41: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

More challenges

•Легко написать неправильно

41

Page 42: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

More challenges

•Легко написать неправильно•Частые перебалансировки consumer group

42

Page 43: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

More challenges

•Легко написать неправильно•Частые перебалансировки consumer group•Управление распределенными consumer-ами

43

Page 44: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

More challenges

•Легко написать неправильно•Частые перебалансировки consumer group•Управление распределенными consumer-ами•Задержки, синхронизация, утилизация ресурсов

44

Page 45: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

45

Page 46: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Реактивные приложения

46

https://www.reactivemanifesto.org/http://reactivex.io/

Page 47: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Реактивные приложения

•Событийно-ориентированные

47

https://www.reactivemanifesto.org/http://reactivex.io/

Page 48: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Реактивные приложения

•Событийно-ориентированные•Масштабируемые

48

https://www.reactivemanifesto.org/http://reactivex.io/

Page 49: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Реактивные приложения

•Событийно-ориентированные•Масштабируемые•Отказоустойчивые

49

https://www.reactivemanifesto.org/http://reactivex.io/

Page 50: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Реактивные приложения

•Событийно-ориентированные•Масштабируемые•Отказоустойчивые•Отзывчивые

50

https://www.reactivemanifesto.org/http://reactivex.io/

Page 51: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Pull-модель

51

public interface IEnumerable{

IEnumerator GetEnumerator();}

public interface IEnumerator{

bool MoveNext();

object Current { get; }

void Reset();}

Page 52: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Push-модель

52

public interface IObservable<out T>{

IDisposable Subscribe(IObserver<T> observer);}

public interface IObserver<in T>{

void OnCompleted();

void OnError(Exception error);

void OnNext(T value);}

Page 53: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

void OnMessage(object sender, Message<Null, string> message) => messages.Add(message);

void OnEof(object sender, TopicPartitionOffset offset) => isEof = true;

consumer.OnMessage += OnMessage;consumer.OnPartitionEOF += OnEof;

53

Page 54: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

IEnumerable<string> topics;var observable =

Observable.FromEventPattern<Message<Null, string>>(x =>

{consumer.OnMessage += x;consumer.Subscribe(topics);

}, x => {

consumer.Unsubscribe();consumer.OnMessage -= x;

}).Select(x => x.EventArgs);

54

Page 55: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

IEnumerable<string> topics;var observable =

Observable.FromEventPattern<Message<Null, string>>(x =>

{consumer.OnMessage += x;consumer.Subscribe(topics);

}, x => {

consumer.Unsubscribe();consumer.OnMessage -= x;

}).Select(x => x.EventArgs);

55

Page 56: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

IEnumerable<string> topics;var observable =

Observable.FromEventPattern<Message<Null, string>>(x =>

{consumer.OnMessage += x;consumer.Subscribe(topics);

}, x => {

consumer.Unsubscribe();consumer.OnMessage -= x;

}).Select(x => x.EventArgs);

56

Page 57: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Rx Kafka Consumer Wrapper

57

Page 58: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var observable = consumerWrapper.Consume(token);

58

Page 59: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var observable = consumerWrapper.Consume(token);

59

Page 60: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var observable = consumerWrapper.Consume(token);

var subscription = observable.Buffer(batchSize).Subscribe(

messages =>{

foreach (var message in messages){

Console.WriteLine(message.Value);consumerWrapper.CommitAsync(message)

.GetAwaiter().GetResult();}

});

60

Page 61: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var observable = consumerWrapper.Consume(token);

var subscription = observable.Buffer(batchSize).Subscribe(

messages =>{

foreach (var message in messages){

Console.WriteLine(message.Value);consumerWrapper.CommitAsync(message)

.GetAwaiter().GetResult();}

});

61

Page 62: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

var observable = consumerWrapper.Consume(token);

var subscription = observable.Buffer(batchSize).Subscribe(

messages =>{

foreach (var message in messages){

Console.WriteLine(message.Value);consumerWrapper.CommitAsync(message)

.GetAwaiter().GetResult();}

});

62

Page 63: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

DEMO: Kafka + Rx

63

Page 64: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

64

Page 65: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

65

Page 66: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

66

Storage API

High-level API

S3 Storage

Page 67: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

67

Storage API

High-level API

S3 Storage

Page 68: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

68

Storage API

High-level API

S3 Storage

Page 69: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

69

Storage API

High-level API

S3 Storage

Page 70: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные изменения

70

Storage API

High-level API

S3 Storage

Page 71: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные измененияНеизменяемость (immutability)

71

Page 72: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные измененияНеизменяемость (immutability)

•Версионирование данных

72

Page 73: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные измененияНеизменяемость (immutability)

•Версионирование данных•Данные + события

73

Page 74: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Распределенные измененияНеизменяемость (immutability)

•Версионирование данных•Данные + события•Данные = события (event sourcing)

74

Page 75: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

75

Storage API

High-level API

S3 Storage

Page 76: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

76

Storage API

High-level API

S3 Storage

Page 77: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

77

Storage API

High-level API

S3 Storage

Page 78: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Неблокирующие изменения

78

Page 79: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Неблокирующие изменения

79

Storage API

High-level API

S3 Storage

Page 80: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Неблокирующие изменения

80

Storage API

High-level API

StorageQueue

Page 81: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Неблокирующие изменения

81

Worker

StorageQueue

/

Page 82: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Неблокирующие изменения

82

StorageQueue

Worker /

Page 83: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Неблокирующие изменения

83

StorageQueue

Worker /

Page 84: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Краткие итоги

84

Page 85: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Краткие итоги•Микросервисы не появляются сами по себе

85

Page 86: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Краткие итоги•Микросервисы не появляются сами по себе•Управление изменениями в приложении значительно усложняется

86

Page 87: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Краткие итоги•Микросервисы не появляются сами по себе•Управление изменениями в приложении значительно усложняется•Apache Kafka упрощает асинхронные взаимодействия

87

Page 88: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Краткие итоги•Микросервисы не появляются сами по себе•Управление изменениями в приложении значительно усложняется•Apache Kafka упрощает асинхронные взаимодействия•Реактивный подход убирает границы между компонентами приложения

88

Page 89: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Полезные ссылки

https://github.com/denisivan0v/highload-2017https://github.com/2gis/nuclear-vstore

89

Page 90: Реактивные микросервисы с Apache Kafka / Денис Иванов (2ГИС)

Спасибо! Вопросы?

Денис Иванов@[email protected]://github.com/denisivan0v

90