Подход Bkkbrad, пожалуй, наиболее эффективен в том смысле, что количество записей, отправляемых каждым картографом, составляет (максимум) K. С другой стороны, обратите внимание, что предполагается, что сам образец (то есть K элементов) помещается в память одного редуктора.
Если это не так, у вас может возникнуть искушение просто использовать полностью распределенный подход, в котором каждая совпадающая строка назначается картографом случайным целым числом в {1, .., K}, а затем фаза сокращения выбирает один элемент для каждого ключа (также см. этот вопрос ). Проблема с этим подходом заключается в том, что может случиться так, что случайно определенным клавишам не будет назначена строка, и в этом случае окончательная выборка будет иметь меньше K элементов. Даже если это случается с небольшой вероятностью, если K намного меньше общего числа строк N, это произойдет с постоянной вероятностью, если K будет постоянной долей N (скажем, когда K = N / 3).
Решение, которое работает, состоит в следующем: предположим, что у нас есть B сегментов и мы сначала генерируем случайный порядок элементов, помещая каждый элемент в случайный сегмент, а затем генерируя случайный порядок в каждом сегменте. Элементы в первом ведре считаются меньшими (по отношению к упорядочению), чем элементы во втором ведре и так далее. Затем, если мы хотим выбрать выборку размера K, мы можем собрать все элементы в первых j сегментах, если они в целом содержат количество элементов t меньше K, а затем выбрать оставшиеся элементы K-t из следующего сегмента. Здесь B - такой параметр, что N / B элементы помещаются в память. Ключевым аспектом является то, что сегменты могут обрабатываться параллельно.
Mapper: Вывести все подходящие строки, каждая со случайным ключом (j, r), где j - случайное целое число в {1, .., B}, а r - случайное число с плавающей точкой. Кроме того, следите за количеством элементов с ключом меньше j (для 1 <= j <= B) и передавайте эту информацию в редукторы. </p>
Перестановка: разбиение по j и вторичная сортировка по r.
Редуктор: рассмотрим блок j и предположим, что редуктор знает, сколько элементов в сегментах меньше, чем j, и сколько в сегменте j (путем агрегирования информации, полученной преобразователями). Если количество элементов в сегментах меньше или равно j меньше или равно K, выведите все элементы в сегменте j; если число элементов с ковшом, строго меньшим, чем j, составляет t
Я не знаю более простого решения этой проблемы, но было бы неплохо, если бы он был.
Вы можете найти более подробную информацию здесь, в моем блоге .