[{"data":1,"prerenderedAt":1213},["ShallowReactive",2],{"content:\u002F08-kafka\u002F02-topics-partitions-ordering":3},{"title":4,"description":5,"path":6,"body":7},"Kafka topics, partitions и гарантии порядка","Самая частая ошибка в Kafka - ожидать глобальный порядок сообщений в topic. Kafka гарантирует порядок только внутри одной partition. Если topic разбит на 12 partitions, это 12 независимых логов, которые пишутся и читаются параллельно.","\u002F08-kafka\u002F02-topics-partitions-ordering",{"type":8,"value":9,"toc":1197},"minimark",[10,14,23,34,37,40,45,59,104,107,110,112,116,119,125,128,144,151,154,232,239,257,259,263,266,338,341,347,350,352,356,359,365,368,371,373,377,380,386,389,392,394,398,404,464,475,477,480,488,491,497,500,511,518,520,524,527,533,536,542,549,551,555,558,573,576,582,585,599,601,605,608,625,628,630,634,698,701,703,707,752,754,758,784,786,790,819,1013,1193],[11,12,4],"h1",{"id":13},"kafka-topics-partitions-и-гарантии-порядка",[15,16,17,18,22],"p",{},"Самая частая ошибка в Kafka - ожидать глобальный порядок сообщений в topic. Kafka гарантирует порядок ",[19,20,21],"strong",{},"только внутри одной partition",". Если topic разбит на 12 partitions, это 12 независимых логов, которые пишутся и читаются параллельно.",[24,25,31],"pre",{"className":26,"code":28,"language":29,"meta":30},[27],"language-text","topic: orders\n\npartition 0: [o-1 created][o-1 paid][o-1 shipped]\npartition 1: [o-2 created][o-2 cancelled]\npartition 2: [o-3 created][o-4 created][o-3 paid]\n\nПорядок есть внутри каждой линии.\nГлобального порядка между линиями нет.\n","text","",[32,33,28],"code",{"__ignoreMap":30},[15,35,36],{},"Это не недостаток, а компромисс ради масштабирования. Чтобы Kafka могла обрабатывать много данных, она делит topic на partitions. Ваша задача как backend-разработчика - выбрать key так, чтобы нужный вам порядок оказался внутри одной partition.",[38,39],"hr",{},[41,42,44],"h2",{"id":43},"topic-имя-потока-partition-единица-параллелизма","Topic - имя потока, partition - единица параллелизма",[15,46,47,48,51,52,51,55,58],{},"Topic задаёт доменную категорию: ",[32,49,50],{},"orders.events",", ",[32,53,54],{},"payments.events",[32,56,57],{},"users.changelog",". Partition задаёт физическое разделение потока.",[60,61,62,76],"table",{},[63,64,65],"thead",{},[66,67,68,73],"tr",{},[69,70,72],"th",{"align":71},"left","Количество partitions",[69,74,75],{"align":71},"Что меняется",[77,78,79,88,96],"tbody",{},[66,80,81,85],{},[82,83,84],"td",{"align":71},"1",[82,86,87],{"align":71},"Простой порядок во всём topic, но низкий параллелизм.",[66,89,90,93],{},[82,91,92],{"align":71},"3",[82,94,95],{"align":71},"Можно читать тремя consumers внутри одной group.",[66,97,98,101],{},[82,99,100],{"align":71},"24",[82,102,103],{"align":71},"Больше throughput, но больше файлов, metadata и rebalancing-стоимости.",[15,105,106],{},"Партиции нельзя выбирать \"на всякий случай бесконечно много\". Каждая partition - это логи на диске, replication, metadata в cluster, участие в leader election и rebalance.",[15,108,109],{},"Практическое правило: partitions выбирают под ожидаемый throughput, количество consumers и запас роста. Увеличить partitions обычно можно. Уменьшить - нет, только пересоздавать topic или переносить данные.",[38,111],{},[41,113,115],{"id":114},"keying-как-producer-выбирает-partition","Keying: как producer выбирает partition",[15,117,118],{},"Producer отправляет record с key или без key. Если key есть, partition обычно выбирается хешем:",[24,120,123],{"className":121,"code":122,"language":29,"meta":30},[27],"partition = hash(key) % number_of_partitions\n",[32,124,122],{"__ignoreMap":30},[15,126,127],{},"Это значит:",[129,130,131,135,138,141],"ul",{},[132,133,134],"li",{},"одинаковый key обычно попадает в одну partition;",[132,136,137],{},"порядок для одного key сохраняется;",[132,139,140],{},"разные keys могут попадать в разные partitions;",[132,142,143],{},"при увеличении количества partitions распределение новых сообщений может измениться.",[15,145,146,147,150],{},"Последний пункт опасен для production. Если ",[32,148,149],{},"hash(key) % partitions"," начал давать другую partition, новые события того же key могут поехать в новую partition, пока старые ещё лежат в старой. Между двумя partitions Kafka не даёт порядка, поэтому увеличение partitions для topic с жёстким per-key ordering требует отдельного плана: окно остановки, новый topic, миграция, dual write\u002Fread или осознанное принятие риска.",[15,152,153],{},"Примеры key:",[60,155,156,169],{},[63,157,158],{},[66,159,160,163,166],{},[69,161,162],{"align":71},"Topic",[69,164,165],{"align":71},"Хороший key",[69,167,168],{"align":71},"Почему",[77,170,171,185,200,217],{},[66,172,173,177,182],{},[82,174,175],{"align":71},[32,176,50],{},[82,178,179],{"align":71},[32,180,181],{},"order_id",[82,183,184],{"align":71},"Все события заказа идут последовательно.",[66,186,187,192,197],{},[82,188,189],{"align":71},[32,190,191],{},"users.events",[82,193,194],{"align":71},[32,195,196],{},"user_id",[82,198,199],{"align":71},"События пользователя не перемешиваются.",[66,201,202,206,214],{},[82,203,204],{"align":71},[32,205,54],{},[82,207,208,211,212],{"align":71},[32,209,210],{},"payment_id"," или ",[32,213,181],{},[82,215,216],{"align":71},"Зависит от нужного порядка.",[66,218,219,224,229],{},[82,220,221],{"align":71},[32,222,223],{},"audit.events",[82,225,226],{"align":71},[32,227,228],{},"tenant_id:user_id",[82,230,231],{"align":71},"Можно сохранить порядок действий пользователя внутри tenant.",[15,233,234,235,238],{},"Плохой key - случайный UUID для каждого события, если бизнесу нужен порядок по заказу. Плохой key - константа ",[32,236,237],{},"\"all\"",", если вы случайно отправляете весь поток в одну partition и убиваете параллелизм.",[15,240,241,242,245,246,249,250,51,253,256],{},"Отдельная проблема - ",[19,243,244],{},"hot key",". Если 40% событий приходят по одному ",[32,247,248],{},"tenant_id",", то одна partition будет отставать, даже если topic имеет 24 partitions и cluster выглядит свободным. Иногда key приходится делать составным: ",[32,251,252],{},"tenant_id:entity_id",[32,254,255],{},"provider:currency_pair"," или другой вариант, который сохраняет нужный порядок, но распределяет нагрузку.",[38,258],{},[41,260,262],{"id":261},"ordering-guarantees","Ordering guarantees",[15,264,265],{},"Kafka даёт несколько уровней порядка.",[60,267,268,281],{},[63,269,270],{},[66,271,272,275,278],{},[69,273,274],{"align":71},"Гарантия",[69,276,277],{"align":71},"Работает?",[69,279,280],{"align":71},"Условие",[77,282,283,294,305,316,327],{},[66,284,285,288,291],{},[82,286,287],{"align":71},"Порядок внутри partition",[82,289,290],{"align":71},"Да",[82,292,293],{"align":71},"Records записаны в partition последовательно.",[66,295,296,299,302],{},[82,297,298],{"align":71},"Порядок для одного key",[82,300,301],{"align":71},"Обычно да",[82,303,304],{"align":71},"Key стабильно попадает в одну partition.",[66,306,307,310,313],{},[82,308,309],{"align":71},"Порядок между partitions",[82,311,312],{"align":71},"Нет",[82,314,315],{"align":71},"Partitions независимы.",[66,317,318,321,324],{},[82,319,320],{"align":71},"Порядок после retry producer",[82,322,323],{"align":71},"Да, если правильно настроено",[82,325,326],{"align":71},"Idempotent producer, bounded in-flight requests.",[66,328,329,332,335],{},[82,330,331],{"align":71},"Порядок после consumer parallel processing",[82,333,334],{"align":71},"Не автоматически",[82,336,337],{"align":71},"Нужна осторожная модель обработки.",[15,339,340],{},"Consumer может сломать порядок, даже если Kafka его сохранила. Например, вы читаете partition последовательно, но отправляете сообщения в worker pool, где второе событие обработалось раньше первого. Для событий одного key это может быть критично.",[24,342,345],{"className":343,"code":344,"language":29,"meta":30},[27],"Kafka partition:  A1 -> A2 -> A3\nWorker pool:      A2 finished first, A1 still running\n\nРезультат в БД может стать неконсистентным.\n",[32,346,344],{"__ignoreMap":30},[15,348,349],{},"Если порядок важен, обрабатывайте partition последовательно или шардируйте worker pool по key.",[38,351],{},[41,353,355],{"id":354},"replication-factor","Replication factor",[15,357,358],{},"Replication factor показывает, сколько копий partition хранит Kafka.",[24,360,363],{"className":361,"code":362,"language":29,"meta":30},[27],"topic orders, partition 0, replication.factor=3\n\nBroker 1: leader   orders-0\nBroker 2: follower orders-0\nBroker 3: follower orders-0\n",[32,364,362],{"__ignoreMap":30},[15,366,367],{},"Leader принимает read\u002Fwrite для partition. Followers копируют данные с leader. Если broker с leader умер, Kafka выбирает нового leader из актуальных replicas.",[15,369,370],{},"Replication factor обычно ставят 3 в production. Это не \"магическая защита от всего\", а компромисс: можно пережить потерю одного broker без потери доступности при нормальных настройках.",[38,372],{},[41,374,376],{"id":375},"isr-in-sync-replicas","ISR: in-sync replicas",[15,378,379],{},"ISR - это replicas, которые не отстали от leader сильнее допустимого. Не все followers автоматически считаются безопасными кандидатами.",[24,381,384],{"className":382,"code":383,"language":29,"meta":30},[27],"orders-0\n\nleader: broker-1 offset=1050\nfollower broker-2 offset=1050  -> ISR\nfollower broker-3 offset=1001  -> out of sync\n",[32,385,383],{"__ignoreMap":30},[15,387,388],{},"ISR важен для durability. Если producer требует подтверждения от всех in-sync replicas, Kafka может гарантировать, что запись есть не только на leader.",[15,390,391],{},"Но ISR может сжиматься. Если followers не успевают за leader из-за сети, диска или нагрузки, они выпадают из ISR. Тогда cluster становится более хрупким.",[38,393],{},[41,395,397],{"id":396},"producer-acks","Producer acks",[15,399,400,403],{},[32,401,402],{},"acks"," определяет, когда broker отвечает producer \"запись принята\".",[60,405,406,420],{},[63,407,408],{},[66,409,410,414,417],{},[69,411,412],{"align":71},[32,413,402],{},[69,415,416],{"align":71},"Когда producer получает успех",[69,418,419],{"align":71},"Риск",[77,421,422,435,447],{},[66,423,424,429,432],{},[82,425,426],{"align":71},[32,427,428],{},"0",[82,430,431],{"align":71},"Не ждёт broker вообще",[82,433,434],{"align":71},"Максимальный риск потери.",[66,436,437,441,444],{},[82,438,439],{"align":71},[32,440,84],{},[82,442,443],{"align":71},"Leader записал record",[82,445,446],{"align":71},"Потеря возможна, если leader умер до replication.",[66,448,449,458,461],{},[82,450,451,454,455],{"align":71},[32,452,453],{},"all"," \u002F ",[32,456,457],{},"-1",[82,459,460],{"align":71},"Leader и ISR подтвердили запись",[82,462,463],{"align":71},"Лучший durability, выше latency.",[15,465,466,467,470,471,474],{},"Для production-событий обычно выбирают ",[32,468,469],{},"acks=all"," вместе с ",[32,472,473],{},"min.insync.replicas",".",[38,476],{},[41,478,473],{"id":479},"mininsyncreplicas",[15,481,482,484,485,487],{},[32,483,473],{}," говорит, сколько replicas должно быть в ISR, чтобы запись с ",[32,486,469],{}," считалась успешной.",[15,489,490],{},"Типичная production-связка:",[24,492,495],{"className":493,"code":494,"language":29,"meta":30},[27],"replication.factor=3\nmin.insync.replicas=2\nproducer acks=all\n",[32,496,494],{"__ignoreMap":30},[15,498,499],{},"Что это даёт:",[129,501,502,505,508],{},[132,503,504],{},"запись успешна, если её подтвердили минимум две in-sync replicas;",[132,506,507],{},"если доступна только одна replica, producer получит ошибку;",[132,509,510],{},"система выбирает отказ записи вместо тихой потери durability.",[15,512,513,514,517],{},"Это важная мысль: хорошие настройки Kafka иногда ",[19,515,516],{},"ломают запись",", чтобы не принять данные в небезопасном состоянии. Backend должен уметь обработать такую ошибку: retry, circuit breaker, outbox, degradation.",[38,519],{},[41,521,523],{"id":522},"leaderfollower-и-failover","Leader\u002Ffollower и failover",[15,525,526],{},"Каждая partition имеет leader. Producer и consumer работают через leader. Followers догоняют leader.",[24,528,531],{"className":529,"code":530,"language":29,"meta":30},[27],"Client\n  |\n  v\nBroker 1 leader for orders-0\n  | replication\n  +--> Broker 2 follower\n  +--> Broker 3 follower\n",[32,532,530],{"__ignoreMap":30},[15,534,535],{},"Если broker 1 падает:",[24,537,540],{"className":538,"code":539,"language":29,"meta":30},[27],"Broker 2 becomes leader for orders-0\nProducer refreshes metadata\nConsumer reconnects\n",[32,541,539],{"__ignoreMap":30},[15,543,544,545,548],{},"В этот момент возможны временные ошибки: ",[32,546,547],{},"NOT_LEADER_OR_FOLLOWER",", timeout, disconnect. Нормальный Kafka client умеет обновлять metadata и повторять операции, но ваш код всё равно должен иметь context timeout и понятную обработку ошибок.",[38,550],{},[41,552,554],{"id":553},"как-выбирать-partitions","Как выбирать partitions",[15,556,557],{},"Простой ориентир:",[559,560,561,564,567,570],"ol",{},[132,562,563],{},"Оцените throughput: сколько MB\u002Fs пишем и читаем.",[132,565,566],{},"Оцените максимальное количество consumers внутри одной group.",[132,568,569],{},"Подумайте о key cardinality: достаточно ли разных keys, чтобы равномерно распределиться.",[132,571,572],{},"Заложите рост, но не создавайте тысячи partitions без необходимости.",[15,574,575],{},"Пример:",[24,577,580],{"className":578,"code":579,"language":29,"meta":30},[27],"orders.events:\n  partitions: 12\n  replication.factor: 3\n  min.insync.replicas: 2\n  key: order_id\n",[32,581,579],{"__ignoreMap":30},[15,583,584],{},"Такой topic можно параллельно читать до 12 consumers внутри одной group. События одного заказа будут идти в одну partition.",[15,586,587,588,591,592,595,596,598],{},"Для RateDesk событие ",[32,589,590],{},"RateUpdated"," выглядит простым, но key всё равно является архитектурным решением. Key по ",[32,593,594],{},"currency_pair"," сохраняет порядок обновлений пары из разных источников хуже, если источники конфликтуют. Key по ",[32,597,255],{}," лучше изолирует источники, но downstream должен сам решать, какой provider сейчас главный. Это не задача Kafka, а доменное правило.",[38,600],{},[41,602,604],{"id":603},"capacity-и-стоимость-partitions","Capacity и стоимость partitions",[15,606,607],{},"Partitions влияют не только на throughput:",[129,609,610,613,616,619,622],{},[132,611,612],{},"больше partitions = больше открытых файлов, metadata и controller work;",[132,614,615],{},"rebalance занимает дольше, если group владеет тысячами partitions;",[132,617,618],{},"leader election и recovery становятся тяжелее;",[132,620,621],{},"слишком много маленьких partitions ухудшают batching и compression;",[132,623,624],{},"слишком мало partitions ограничивают consumer parallelism и могут создать lag.",[15,626,627],{},"Хороший capacity plan связывает expected MB\u002Fs, размер record, retention, replication factor, количество consumer groups и допустимый lag. \"Поставим 100 partitions на всякий случай\" часто так же плохо, как \"оставим одну\".",[38,629],{},[41,631,633],{"id":632},"типичные-компромиссы","Типичные компромиссы",[60,635,636,646],{},[63,637,638],{},[66,639,640,643],{},[69,641,642],{"align":71},"Нужно",[69,644,645],{"align":71},"Компромисс",[77,647,648,656,664,674,682,690],{},[66,649,650,653],{},[82,651,652],{"align":71},"Глобальный порядок",[82,654,655],{"align":71},"1 partition, но низкий throughput.",[66,657,658,661],{},[82,659,660],{"align":71},"Высокий throughput",[82,662,663],{"align":71},"Много partitions, но нет глобального порядка.",[66,665,666,669],{},[82,667,668],{"align":71},"Высокая durability",[82,670,671,673],{"align":71},[32,672,469],{},", больше latency и возможные ошибки при деградации ISR.",[66,675,676,679],{},[82,677,678],{"align":71},"Низкая latency",[82,680,681],{"align":71},"Меньшие batch и слабее durability-настройки.",[66,683,684,687],{},[82,685,686],{"align":71},"Равномерная нагрузка",[82,688,689],{"align":71},"Хороший key, но иногда сложнее сохранить доменный порядок.",[66,691,692,695],{},[82,693,694],{"align":71},"Будущий рост partitions",[82,696,697],{"align":71},"Легче масштабировать throughput, но можно сломать порядок для key при изменении mapping.",[15,699,700],{},"Kafka почти всегда про осознанный баланс. \"Поставим 100 partitions, acks=1, потом разберёмся\" - плохая стратегия для доменных событий.",[38,702],{},[41,704,706],{"id":705},"вопросы-на-собеседовании","Вопросы на собеседовании",[129,708,709,712,715,718,721,724,736,743,746,749],{},[132,710,711],{},"Где Kafka гарантирует порядок сообщений?",[132,713,714],{},"Почему одинаковый key обычно попадает в одну partition?",[132,716,717],{},"Что произойдёт с порядком при worker pool на стороне consumer?",[132,719,720],{},"Чем leader partition отличается от follower?",[132,722,723],{},"Что такое ISR?",[132,725,726,727,51,730,732,733,735],{},"Как связаны ",[32,728,729],{},"replication.factor",[32,731,469],{}," и ",[32,734,473],{},"?",[132,737,738,739,742],{},"Почему ",[32,740,741],{},"acks=1"," может потерять данные при падении leader?",[132,744,745],{},"Можно ли уменьшить количество partitions в существующем topic?",[132,747,748],{},"Почему увеличение partitions может быть опасно для key-based ordering?",[132,750,751],{},"Как hot key проявится в consumer lag?",[38,753],{},[41,755,757],{"id":756},"практика","Практика",[559,759,760,766,769,781],{},[132,761,762,763,765],{},"Для topic ",[32,764,50],{}," выберите key и объясните, какие события должны сохранять порядок.",[132,767,768],{},"Нарисуйте схему topic с 6 partitions и consumer group из 4 consumers: кому сколько partitions достанется?",[132,770,771,772,51,775,51,778,780],{},"Объясните поведение producer при ",[32,773,774],{},"replication.factor=3",[32,776,777],{},"min.insync.replicas=2",[32,779,469],{},", если жив только один broker.",[132,782,783],{},"Придумайте пример, где глобальный порядок важнее throughput, и topic стоит сделать с одной partition.",[38,785],{},[41,787,789],{"id":788},"интерактивная-практика","Интерактивная практика",[791,792,795,797,814],"quiz",{"answer":84,"id":793,"xp":794},"kafka-partitions-q1","10",[15,796,711],{},[798,799,800],"template",{"v-slot:options":30},[129,801,802,805,808,811],{},[132,803,804],{},"Только внутри одной partition",[132,806,807],{},"Между всеми partitions одного topic",[132,809,810],{},"Между всеми topics одного broker",[132,812,813],{},"Только внутри consumer group, независимо от partition",[798,815,816],{"v-slot:explanation":30},[15,817,818],{},"Partition — это отдельный append-only log. Порядок есть внутри него, но Kafka не синхронизирует глобальный порядок между partitions.",[820,821,825,828,1008],"predict",{"answer":822,"id":823,"xp":824},"same\\nmaybe-different","kafka-partitions-p1","15",[15,826,827],{},"Что выведет программа?",[798,829,830],{"v-slot:code":30},[24,831,835],{"className":832,"code":833,"language":834,"meta":30,"style":30},"language-go shiki shiki-themes github-dark","package main\n\nimport \"fmt\"\n\nfunc partitionMapping(sameKey bool) string {\n    if sameKey {\n        return \"same\"\n    }\n    return \"maybe-different\"\n}\n\nfunc main() {\n    fmt.Println(partitionMapping(true))\n    fmt.Println(partitionMapping(false))\n}\n","go",[32,836,837,850,857,873,878,907,916,925,931,940,946,951,962,985,1003],{"__ignoreMap":30},[838,839,842,846],"span",{"class":840,"line":841},"line",1,[838,843,845],{"class":844},"snl16","package",[838,847,849],{"class":848},"svObZ"," main\n",[838,851,853],{"class":840,"line":852},2,[838,854,856],{"emptyLinePlaceholder":855},true,"\n",[838,858,860,863,867,870],{"class":840,"line":859},3,[838,861,862],{"class":844},"import",[838,864,866],{"class":865},"sU2Wk"," \"",[838,868,869],{"class":848},"fmt",[838,871,872],{"class":865},"\"\n",[838,874,876],{"class":840,"line":875},4,[838,877,856],{"emptyLinePlaceholder":855},[838,879,881,884,887,891,895,898,901,904],{"class":840,"line":880},5,[838,882,883],{"class":844},"func",[838,885,886],{"class":848}," partitionMapping",[838,888,890],{"class":889},"s95oV","(",[838,892,894],{"class":893},"s9osk","sameKey",[838,896,897],{"class":844}," bool",[838,899,900],{"class":889},") ",[838,902,903],{"class":844},"string",[838,905,906],{"class":889}," {\n",[838,908,910,913],{"class":840,"line":909},6,[838,911,912],{"class":844},"    if",[838,914,915],{"class":889}," sameKey {\n",[838,917,919,922],{"class":840,"line":918},7,[838,920,921],{"class":844},"        return",[838,923,924],{"class":865}," \"same\"\n",[838,926,928],{"class":840,"line":927},8,[838,929,930],{"class":889},"    }\n",[838,932,934,937],{"class":840,"line":933},9,[838,935,936],{"class":844},"    return",[838,938,939],{"class":865}," \"maybe-different\"\n",[838,941,943],{"class":840,"line":942},10,[838,944,945],{"class":889},"}\n",[838,947,949],{"class":840,"line":948},11,[838,950,856],{"emptyLinePlaceholder":855},[838,952,954,956,959],{"class":840,"line":953},12,[838,955,883],{"class":844},[838,957,958],{"class":848}," main",[838,960,961],{"class":889},"() {\n",[838,963,965,968,971,973,976,978,982],{"class":840,"line":964},13,[838,966,967],{"class":889},"    fmt.",[838,969,970],{"class":848},"Println",[838,972,890],{"class":889},[838,974,975],{"class":848},"partitionMapping",[838,977,890],{"class":889},[838,979,981],{"class":980},"sDLfK","true",[838,983,984],{"class":889},"))\n",[838,986,988,990,992,994,996,998,1001],{"class":840,"line":987},14,[838,989,967],{"class":889},[838,991,970],{"class":848},[838,993,890],{"class":889},[838,995,975],{"class":848},[838,997,890],{"class":889},[838,999,1000],{"class":980},"false",[838,1002,984],{"class":889},[838,1004,1006],{"class":840,"line":1005},15,[838,1007,945],{"class":889},[798,1009,1010],{"v-slot:hint":30},[15,1011,1012],{},"Одинаковый key обычно попадает в одну partition, а разные key могут распределиться по разным partitions.",[1014,1015,1019,1032,1178],"code-task",{"expected":1016,"id":1017,"xp":1018},"reject\\naccept\\naccept","kafka-partitions-ct1","20",[15,1020,1021,1022,1025,1026,1028,1029,474],{},"Реализуй ",[32,1023,1024],{},"WriteDecision",": при ",[32,1027,469],{}," запись можно принять, только если число in-sync replicas не меньше ",[32,1030,1031],{},"minISR",[798,1033,1034],{"v-slot:template":30},[24,1035,1037],{"className":832,"code":1036,"language":834,"meta":30,"style":30},"package main\n\nimport \"fmt\"\n\nfunc WriteDecision(inSyncReplicas int, minISR int) string {\n    return \"todo\"\n}\n\nfunc main() {\n    fmt.Println(WriteDecision(1, 2))\n    fmt.Println(WriteDecision(2, 2))\n    fmt.Println(WriteDecision(3, 2))\n}\n",[32,1038,1039,1045,1049,1059,1063,1090,1097,1101,1105,1113,1134,1154,1174],{"__ignoreMap":30},[838,1040,1041,1043],{"class":840,"line":841},[838,1042,845],{"class":844},[838,1044,849],{"class":848},[838,1046,1047],{"class":840,"line":852},[838,1048,856],{"emptyLinePlaceholder":855},[838,1050,1051,1053,1055,1057],{"class":840,"line":859},[838,1052,862],{"class":844},[838,1054,866],{"class":865},[838,1056,869],{"class":848},[838,1058,872],{"class":865},[838,1060,1061],{"class":840,"line":875},[838,1062,856],{"emptyLinePlaceholder":855},[838,1064,1065,1067,1070,1072,1075,1078,1080,1082,1084,1086,1088],{"class":840,"line":880},[838,1066,883],{"class":844},[838,1068,1069],{"class":848}," WriteDecision",[838,1071,890],{"class":889},[838,1073,1074],{"class":893},"inSyncReplicas",[838,1076,1077],{"class":844}," int",[838,1079,51],{"class":889},[838,1081,1031],{"class":893},[838,1083,1077],{"class":844},[838,1085,900],{"class":889},[838,1087,903],{"class":844},[838,1089,906],{"class":889},[838,1091,1092,1094],{"class":840,"line":909},[838,1093,936],{"class":844},[838,1095,1096],{"class":865}," \"todo\"\n",[838,1098,1099],{"class":840,"line":918},[838,1100,945],{"class":889},[838,1102,1103],{"class":840,"line":927},[838,1104,856],{"emptyLinePlaceholder":855},[838,1106,1107,1109,1111],{"class":840,"line":933},[838,1108,883],{"class":844},[838,1110,958],{"class":848},[838,1112,961],{"class":889},[838,1114,1115,1117,1119,1121,1123,1125,1127,1129,1132],{"class":840,"line":942},[838,1116,967],{"class":889},[838,1118,970],{"class":848},[838,1120,890],{"class":889},[838,1122,1024],{"class":848},[838,1124,890],{"class":889},[838,1126,84],{"class":980},[838,1128,51],{"class":889},[838,1130,1131],{"class":980},"2",[838,1133,984],{"class":889},[838,1135,1136,1138,1140,1142,1144,1146,1148,1150,1152],{"class":840,"line":948},[838,1137,967],{"class":889},[838,1139,970],{"class":848},[838,1141,890],{"class":889},[838,1143,1024],{"class":848},[838,1145,890],{"class":889},[838,1147,1131],{"class":980},[838,1149,51],{"class":889},[838,1151,1131],{"class":980},[838,1153,984],{"class":889},[838,1155,1156,1158,1160,1162,1164,1166,1168,1170,1172],{"class":840,"line":953},[838,1157,967],{"class":889},[838,1159,970],{"class":848},[838,1161,890],{"class":889},[838,1163,1024],{"class":848},[838,1165,890],{"class":889},[838,1167,92],{"class":980},[838,1169,51],{"class":889},[838,1171,1131],{"class":980},[838,1173,984],{"class":889},[838,1175,1176],{"class":840,"line":964},[838,1177,945],{"class":889},[798,1179,1180],{"v-slot:hints":30},[129,1181,1182,1187],{},[132,1183,1184,1186],{},[32,1185,473],{}," задаёт минимальное число ISR для безопасной записи.",[132,1188,1189,1190,1192],{},"Если ISR меньше минимума, producer с ",[32,1191,469],{}," должен получить ошибку.",[1194,1195,1196],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":30,"searchDepth":852,"depth":852,"links":1198},[1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212],{"id":43,"depth":852,"text":44},{"id":114,"depth":852,"text":115},{"id":261,"depth":852,"text":262},{"id":354,"depth":852,"text":355},{"id":375,"depth":852,"text":376},{"id":396,"depth":852,"text":397},{"id":479,"depth":852,"text":473},{"id":522,"depth":852,"text":523},{"id":553,"depth":852,"text":554},{"id":603,"depth":852,"text":604},{"id":632,"depth":852,"text":633},{"id":705,"depth":852,"text":706},{"id":756,"depth":852,"text":757},{"id":788,"depth":852,"text":789},1781022064937]