Предлагаю для обсуждения алгоритм подсчета результатов голосований. Из него следует также состав записей в БД, содержащих исходные данные и результаты голосований, а также количество таких записей. Отмечу сразу, что точки "выверки" - сравнении результатов, полученных разными нодами, я опустил. Несколько слов об этом в конце поста. Как вы правильно подметили, первоначально, на самом нижнем уровне иерархии, все ноды СГ требуется однозначно и фиксировано разделить на группы. Например, по фиксированному ID каждой ноды. И, например, по 1024 ноды в каждой группе. В каждой ноде группы должны храниться исходные данные голосований на всех других нодах данной группы. Это нужно, в первую очередь (по-моему, и в последнюю), для надежного хранения исходных данных по голосованию во всей системе. В результате количество записей в виде исходных данных в каждой ноде зависит от количества проголосовавших в этой группе нод. Очевидно, что реально это будет от единиц до числа, незначительно превышающего 1024 (размер группы нод). Дальнейшее разбиение на группы для подсчета результатов голосований в этих группах производится по разным атрибутам голосующих или по ID самих нод (хотя реальную заинтересованность кого-либо в подсчете результатов голосований именно по группам нод системы трудно представить в реальности). Атрибутом голосующего, однозначно и фиксировано определяющего его принадлежность к той или иной группе, может быть "приписка" его к определенной УИК (книга избирателей), расположенному на территории соответствующей ТИК, далее ОИК. В реальных голосованиях такое разбиение на группы будет чаще всего. В некоторых случаях, в соответствии с запросом заказчика и при наличии у голосующих соответствующих атрибутов, может производиться подсчет голосов по группам, образованным по другим (любым) критериям - пол, возраст, социальное или семейное положение, и т.д. Далее для сокращения текста будем говорить о голосовании с принципом разбиения голосующих по УИК, ТИК, ОИК и ЦИК в вершине иерархии групп. Алгоритм подсчета при разбиении по группам нод, очевидно, отличается лишь в деталях
Итак, голосование идет или уже завершилось. В группе из 1024 нод, могут быть голоса, принадлежащие различным УИК. Понятно, что ВСЕ голоса в СГ, поданные людьми, приписанными к этой УИК, надо где-то агрегировать для подведения итога по этой УИК. Это надо делать в БД тех нод, где голоса этой УИК появились. Каждая такая нода готовит записи, суммирующие исходные голоса по этим УИК. Каждая из записей гласит: на этой ноде проголосовало такое-то количество людей из такой-то УИК. Количество таких записей не должно превышать количества людей, проголосовавших на этой ноде, и, в пределе, не превышает кол-ва людей, приписанных ко всем УИК, "отметившихся" в данной ноде. В реальности, конечно же, это будут единицы-десятки записей, не больше. В итоге на ноде мы получили суммирующие записи по каждой УИК, проявившейся в исходных голосах ноды. Но люди, приписанные к этим УИК, могли проголосовать и на других нодах (те, которые проголосовали в этой группе нод, уже учтены – их голоса уже реплицировались в БД ноды). Для того, чтобы каждая нода могла самостоятельно подвести итоги по этим УИК (и просто для подведения итогов), все записи, относящиеся к указанным УИК, должны собираться со всей СГ на нодах, где эти УИК проявились в результате голосования. Причем, что важно, собираться с других нод и храниться в БД этой ноды в исходном виде - в том, в котором приняты. Каждый раз, когда такая новая запись приходит и записывается в БД ноды, на ней производится новый подсчет голосов по соответствующему УИК. Суммирующая запись заменяет предыдущую в БД и представляет из себя частичные данные группы следующего уровня подведения итогов - ТИК. На уровне ТИК алгоритм полностью повторяется. Суммирующая запись заменяет предыдущую в БД и представляет из себя частичные данные уровня ОИК. Наконец, суммирующая запись, полученная на уровне ОИК, сохраняется в БД ноды и является текущим результатом голосования по всей системе в целом. Если подсчет результатов производится во время голосования, то сверка результатов и выявление фальсификаций - дело непростое. Алгоритм сверки необходимо тщательно продумать - из-за динамичности процесса голосования итоги все время меняются. Подведение итогов и сверка результатов после окончания голосования может быть осложнена недоступностью необходимых данных (нод, на которых они считаются). Процесс сверки результатов при закрытых голосованиях тоже заставляет задуматься. В предложенном алгоритме каждая нода не считает данные по всем группам (УИК). Ведь все исходные данные хранить на всех нодах невозможно. Промежуточные (и окончательные тоже) итоги по всем группам тоже хранить на всех нодах не имеет смысла - ведь это уже результат обработки данных, а не сами исходные данные. Кроме того, очевидно, что предложенный алгоритм кардинально сокращает трафик и размеры БД по сравнению этими (полными) вариантами.
p.s. получился длинный текст. С графическим пояснением было бы значительно нагляднее. Как на форуме разместить рисунок?
|