פֿעיִקייטן פון דיזיינינג אַ דאַטן מאָדעל פֿאַר NoSQL

הקדמה

פֿעיִקייטן פון דיזיינינג אַ דאַטן מאָדעל פֿאַר NoSQL "איר מוזן לויפן ווי שנעל ווי איר קענען נאָר צו בלייַבן אין פּלאַץ,
און צו קומען ערגעץ מוז מען לויפן אמווייניגסטנס צוויי מאל אזוי שנעל!
(c) אַליס אין וואָנדערלאַנד

מיט עטלעכע מאָל צוריק האָט מען מיך געבעטן צו האַלטן אַ לעקציע אַנאַליס אונדזער פירמע אויף דער טעמע פון ​​דיזיינינג דאַטן מאָדעלס, ווייַל זיצן אויף פּראַדזשעקס פֿאַר אַ לאַנג צייַט (מאל פֿאַר עטלעכע יאָרן) מיר פאַרלירן דערזען פון וואָס איז געשעעניש אַרום אונדז אין דער וועלט פון IT טעקנאַלאַדזשיז. אין אונדזער פירמע (עס נאָר כאַפּאַנז) פילע פּראַדזשעקס טאָן ניט נוצן NoSQL דאַטאַבייסיז (לפּחות פֿאַר איצט), אַזוי אין מיין לעקציע איך סעפּעראַטלי באַצאָלט עטלעכע ופמערקזאַמקייט צו זיי מיט די ביישפּיל פון HBase און געפרוווט צו אָריענטירן די פּרעזענטירונג פון דעם מאַטעריאַל צו די. װע ר האב ן ז ײ קײנמא ל ניש ט גענוצ ט האב ן געארבע ט . אין באַזונדער, איך יללוסטראַטעד עטלעכע פון ​​די פֿעיִקייטן פון דאַטן מאָדעל פּלאַן מיט אַ בייַשפּיל איך לייענען עטלעכע יאָרן צוריק אין דעם אַרטיקל "הקדמה צו HB ase Schema Design" דורך Amandeep Khurana. Разбирая примеры, я сравнивал между собой несколько вариантов решения одной и той же задачи, чтобы лучше донести до слушателей основные идеи.

לעצטנס, "פון גאָרנישט צו טאָן," איך געפרעגט זיך די קשיא (דער לאַנג מייַ אָפּרוטעג אין קאַראַנטין איז ספּעציעל קאַנדוסיוו צו דעם), ווי פיל וועט די טעאָרעטיש חשבונות שטימען צו פיר? אַקטואַללי, דאָס איז ווי דער געדאַנק פֿאַר דעם אַרטיקל איז געבוירן. א דעוועלאָפּער וואָס איז ארבעטן מיט NoSQL פֿאַר עטלעכע טעג קען נישט לערנען עפּעס נייַ דערפון (און דעריבער קען מיד האָפּקען האַלב פון דעם אַרטיקל). אָבער פֿאַר אַנאַליס, которые еще не работали плотно с NoSQL, полагаю, она будет полезна для получения базовых представлений об особенностях проектирования моделей данных для HBase.

בייַשפּיל אַנאַליסיס

אין מיין מיינונג, איידער איר אָנהייבן ניצן NoSQL דאַטאַבייסיז, איר דאַרפֿן צו טראַכטן קערפאַלי און וועגן די פּראָס און קאָנס. אָפט די פּראָבלעם קענען זיין סאַלווד מיט טראדיציאנעלן ריליישאַנאַל דבמס. דעריבער, עס איז בעסער נישט צו נוצן NoSQL אָן באַטייַטיק סיבות. אויב איר נאָך באַשלאָסן צו נוצן אַ NoSQL דאַטאַבייס, איר זאָל נעמען אין חשבון אַז די פּלאַן אַפּראָוטשיז דאָ זענען עפּעס אַנדערש. ספּעציעל עטלעכע פון ​​זיי קען זיין ומגעוויינטלעך פֿאַר יענע וואָס האָבן ביז אַהער דעלט בלויז מיט ריליישאַנאַל דבמס (לויט מיין אַבזערוויישאַנז). אַזוי, אין די "ריליישאַנאַל" וועלט, מיר יוזשאַוואַלי אָנהייבן מיט מאָדעלינג די פּראָבלעם פעלד, און בלויז דעמאָלט, אויב נייטיק, דינאָרמאַליז די מאָדעל. אין NoSQL מיר сразу должны учитывать предполагаемые сценарии работы с данными און טכילעס דינאָרמאַלייז די דאַטן. אין דערצו, עס זענען אַ נומער פון אנדערע דיפעראַנסיז, וואָס וועט זיין דיסקאַסט אונטן.

לאָמיר באַטראַכטן די פאלגענדע "סינטעטיש" פּראָבלעם מיט וואָס מיר וועלן פאָרזעצן צו אַרבעטן:

עס איז נייטיק צו פּלאַן אַ סטאָרידזש סטרוקטור פֿאַר די רשימה פון Friends פון ניצערס פון עטלעכע אַבסטראַקט געזעלשאַפטלעך נעץ. צו פאַרפּאָשעטערן, מיר וועלן יבערנעמען אַז אַלע אונדזער קאַנעקשאַנז זענען דירעקטעד (ווי אויף ינסטאַגראַם, נישט לינקעדין). די סטרוקטור זאָל לאָזן איר צו יפעקטיוולי:

  • ענטפֿערן די קשיא צי באַניצער א לייענט באַניצער ב (לייענען מוסטער)
  • Позволять добавлять/удалять связи в случае подписки/отписки пользователя А от пользователя Б (шаблон изменения данных)

פון קורס, עס זענען פילע אָפּציעס פֿאַר סאָלווע דעם פּראָבלעם. אין אַ רעגולער ריליישאַנאַל דאַטאַבייס, מיר וואָלט רובֿ מסתּמא פשוט מאַכן אַ טיש פון באציונגען (עפשער טיפּיש אויב, פֿאַר בייַשפּיל, מיר דאַרפֿן צו קראָם אַ באַניצער גרופּע: משפּחה, אַרבעט, אאז"ו ו, וואָס כולל דעם "פרייַנד"), און צו אַפּטאַמייז אַקסעס גיכקייַט וואָלט לייגן ינדעקסיז / פּאַרטישאַנינג. רובֿ מסתּמא די לעצט טיש וואָלט קוקן עפּעס ווי דאָס:

באַניצער שייַן
friend_id

וואַסיאַ
פעטרוס

וואַסיאַ
Оля

נאכדעם וועל איך פאר קלארקייט און פאר בעסערן פארשטאנד אנווייזן נעמען אנשטאט פאר אידען

אין דעם פאַל פון HBase, מיר וויסן אַז:

  • эффективный поиск, не приводящий к full table scan, возможен исключительно по ключу
    • אין פאַקט, אַז ס וואָס שרייבן סקל קוויריז באַקאַנט צו פילע צו אַזאַ דאַטאַבייסיז איז אַ שלעכט געדאַנק; טעקניקלי, פון קורס, איר קענען שיקן אַ SQL אָנפֿרעג מיט דזשאָינס און אנדערע לאָגיק צו HBase פֿון דער זעלביקער ימפּאַלאַ, אָבער ווי עפעקטיוו וועט עס זיין ...

דעריבער, מיר זענען געצווונגען צו נוצן די באַניצער שייַן ווי אַ שליסל. און מיין ערשטער געדאַנק אויף דער טעמע "וואו און ווי צו קראָם פרענדז IDs?" אפֿשר אַ געדאַנק צו קראָם זיי אין שפאלטן. די מערסט קלאָר ווי דער טאָג און "נאַיוו" אָפּציע וועט קוקן עפּעס ווי דאָס (לאָזן ס רופן עס Вариант 1 (default)פֿאַר ווייַטער דערמאָנען):

RowKey
ספּיקערז

וואַסיאַ
1: Петя
2: Оля
3: Даша

פעטרוס
1: Маша
2: Вася

דאָ, יעדער שורה קאָראַספּאַנדז צו איין נעץ באַניצער. די שפאלטן האבן נעמען: 1, 2,... — לויט דער צאל פרײנד, און די אידען פון פרײנד זײנען פארשפארט אין די שפאלטן. עס איז וויכטיק צו טאָן אַז יעדער רודערן וועט האָבן אַ אַנדערש נומער פון שפאלטן. אין דעם בייַשפּיל אין די פיגור אויבן, איין רודערן האט דריי שפאלטן (1, 2 און 3), און די צווייטע האט בלויז צוויי (1 און 2) - דאָ מיר זיך געניצט צוויי HBase פּראָפּערטיעס וואָס ריליישאַנאַל דאַטאַבייסיז טאָן ניט האָבן:

  • די פיייקייט צו דינאַמיקאַללי טוישן די זאַץ פון שפאלטן (לייג אַ פרייַנד -> לייגן אַ זייַל, אַראָפּנעמען אַ פרייַנד -> ויסמעקן אַ זייַל)
  • פאַרשידענע ראָוז קען האָבן פאַרשידענע זייַל חיבורים

Проверим нашу структуру на соответствие требованиям задачи:

  • לייענען דאַטן: כּדי צו פֿאַרשטיין צי וואַסיאַ איז אַבאָנירן צו אָליאַ, מיר דאַרפֿן צו אַראָפּרעכענען די גאנצע שורה דורך די שליסל RowKey = "Vasya" און סאָרט דורך די זייַל וואַלועס ביז מיר "באַגעגנט" Olya אין זיי. אָדער יטערייט די וואַלועס פון אַלע שפאלטן, "ניט טרעפן" אָליאַ און צוריקקומען די ענטפער פאַלש;
  • עדיטינג דאַטן: אַדינג אַ פרייַנד: פֿאַר אַ ענלעך אַרבעט מיר אויך דאַרפֿן צו אַראָפּרעכענען די גאנצע שורה по ключу RowKey = «Вася», чтобы посчитать общее количество его друзей. Это общее кол-во друзей нам необходимо, чтобы определить номер колонки, в которую надо записать ID нового друга.
  • טשאַנגינג דאַטן: דיליטינג אַ פרייַנד:
    • דאַרפֿן צו אַראָפּרעכענען די גאנצע שורה דורך די שליסל RowKey = "Vasya" און סאָרט דורך די שפאלטן אין סדר צו געפֿינען די איינער אין וואָס די פרייַנד צו ווערן אויסגעמעקט איז רעקאָרדעד;
    • ווייַטער, נאָך דיליטינג אַ פרייַנד, מיר דאַרפֿן צו "יבעררוק" אַלע די דאַטן אין איין זייַל, אַזוי נישט צו באַקומען "גאַפּס" אין זייער נומערינג.

Давайте теперь оценим, насколько данные алгоритмы, которые нам необходимо будет реализовывать на стороне «условного приложения», будут производительны, используя אָ-סימבאַליזאַם. לאָמיר באַצייכענען די גרייס פון אונדזער כייפּאַטעטיקאַל געזעלשאַפטלעך נעץ ווי n. דערנאָך די מאַקסימום נומער פון פרענדז וואָס איינער באַניצער קענען האָבן איז (n-1). מיר קענען נאָך פאַרלאָזן דעם (-1) פֿאַר אונדזער צוועקן, ווייַל אין די פריימווערק פון די נוצן פון אָ-סימבאַלז עס איז אַנימפּאָרטיד.

  • לייענען דאַטן: עס איז נייטיק צו אַראָפּרעכענען די גאנצע שורה און יטערייט דורך אַלע זייַן שפאלטן אין די שיעור. דעם מיטל דער אויבערשטער אָפּשאַצונג פון קאָס וועט זיין בעערעך O (n)
  • עדיטינג דאַטן: אַדינג אַ פרייַנד: צו באַשטימען די נומער פון פרענדז, איר דאַרפֿן צו יטערייט דורך אַלע די שפאלטן פון די רודערן, און אַרייַנלייגן אַ נייַע זייַל => O(n)
  • טשאַנגינג דאַטן: דיליטינג אַ פרייַנד:
    • ענלעך צו אַדינג - איר דאַרפֿן צו גיין דורך אַלע שפאלטן אין די שיעור => O (n)
    • После удаления колонок нам надо «сдвинуть» их. Если реализовывать это «в лоб», то в пределе потребуется еще до (n-1) операций. Но мы здесь и далее в практической части применим иной подход, который будет реализовывать «псевдо-сдвиг» за фиксированное кол-во операций – то есть на него будет тратиться константное время вне зависимости от n. Этим константным временем (если быть точным, то О(2)) по сравнению с О(n) можно пренебречь. Подход проиллюстрирован на рисунке ниже: мы просто копируем данные из «последней» колонки в ту, из которой надо удалить данные, после чего удаляем последнюю колонку:
      פֿעיִקייטן פון דיזיינינג אַ דאַטן מאָדעל פֿאַר NoSQL

אין גאַנץ, אין אַלע סינעריאָוז מיר באקומען אַן אַסימפּטאָטיק קאַמפּיוטיישאַנאַל קאַמפּלעקסיטי פון O (n).
איר האָט מיסטאָמע שוין באמערקט אַז מיר מוזן כּמעט שטענדיק לייענען די גאנצע רודערן פון די דאַטאַבייס, און אין צוויי קאַסעס פון דרייַ, נאָר צו גיין דורך אַלע די שפאלטן און רעכענען די גאַנץ נומער פון פריינט. דעריבער, ווי אַן פּרווון צו אַפּטאַמאַזיישאַן, איר קענען לייגן אַ "ציילן" זייַל, וואָס סטאָרז די גאַנץ נומער פון פרענדז פון יעדער נעץ באַניצער. אין דעם פאַל, מיר קענען נישט לייענען די גאנצע רודערן צו רעכענען די גאַנץ נומער פון פרענדז, אָבער לייענען בלויז איין "ציילן" זייַל. די הויפּט זאַך איז נישט צו פאַרגעסן צו דערהייַנטיקן "ציילן" ווען מאַניפּיאַלייטינג דאַטן. אַז. מיר באַקומען ימפּרוווד אָפּציע 2 (ציילן):

RowKey
ספּיקערז

וואַסיאַ
1: Петя
2: Оля
3: Даша
ציילן: 3

פעטרוס
1: Маша
2: Вася

ציילן: 2

קאַמפּערד מיט דער ערשטער אָפּציע:

  • לייענען דאַטן: для получения ответа на вопрос «Читает ли Вася Олю?» ничего не изменилось => О(n)
  • עדיטינג דאַטן: אַדינג אַ פרייַנד: מיר האָבן פאַרפּאָשעטערט די אַרייַנלייגן פון אַ נייַ פרייַנד, זינט איצט מיר טאָן ניט דאַרפֿן צו לייענען די גאנצע שורה און יטערייט איבער זייַן שפאלטן, אָבער קענען נאָר באַקומען די ווערט פון די "ציילן" זייַל, אאז"ו ו. מיד באַשטימען די זייַל נומער צו אַרייַנלייגן אַ נייַ פרייַנד. דאָס פירט צו אַ רעדוקציע אין קאַמפּיוטיישאַנאַל קאַמפּלעקסיטי צו אָ (1)
  • טשאַנגינג דאַטן: דיליטינג אַ פרייַנד: ווען דיליטינג אַ פרייַנד, מיר קענען אויך נוצן דעם זייַל צו רעדוצירן די נומער פון י / אָ אַפּעריישאַנז ווען "שיפטינג" די דאַטן איין צעל צו די לינקס. אָבער דער נויט צו יטערייט דורך די שפאלטן צו געפֿינען די איינער וואָס דאַרף זיין אויסגעמעקט נאָך בלייבט, אַזוי => O (n)
  • אויף די אנדערע האַנט, איצט ווען אַפּדייטינג דאַטן מיר דאַרפֿן צו דערהייַנטיקן די "ציילן" זייַל יעדער מאָל, אָבער דאָס נעמט קעסיידערדיק צייט, וואָס קענען זיין אָפּגעלאָזן אין די פריימווערק פון אָ-סימבאַלז

אין אַלגעמיין, אָפּציע 2 סימז אַ ביסל מער אָפּטימאַל, אָבער עס איז מער ווי "עוואָלוציע אַנשטאָט פון רעוואָלוציע." צו מאַכן אַ "רעוואָלוציע" מיר וועלן דאַרפֿן Вариант 3 (col).
Перевернем все «с ног на голову»: назначим זייַל נאָמען באַניצער שייַן! וואָס וועט זיין געשריבן אין די זייַל זיך איז ניט מער וויכטיק פֿאַר אונדז, לאָזן עס זיין די נומער 1 (אין אַלגעמיין, נוציק זאכן קענען זיין סטאָרד דאָרט, למשל, די גרופּע "משפּחה / פריינט / אאז"ו ו.). דער צוגאַנג קען יבערראַשן די אַנפּריפּערד "ליימאַן" וואָס האט קיין פריערדיקן דערפאַרונג אין ארבעטן מיט NoSQL דאַטאַבייסיז, אָבער דאָס איז פּונקט דער צוגאַנג וואָס אַלאַוז איר צו נוצן די פּאָטענציעל פון HBase אין דעם אַרבעט פיל מער יפעקטיוולי:

RowKey
ספּיקערז

וואַסיאַ
פעטיאַ: 1
אָליאַ: 1
דאַשאַ: 1

פעטרוס
מאַשאַ: 1
וואַסיאַ: 1

Здесь мы получаем сразу несколько преимуществ. Чтобы их понять, проанализируем новую структуру и оценим вычислительную сложность:

  • לייענען דאַטן: צו ענטפֿערן די קשיא צי וואַסיאַ איז אַבאָנירן צו אָליאַ, עס איז גענוג צו לייענען איין זייַל "אָליאַ": אויב עס איז דאָרט, דער ענטפער איז אמת, אויב נישט - פאַלש => אָ(1)
  • עדיטינג דאַטן: אַדינג אַ פרייַנד: אַדינג אַ פרייַנד: נאָר לייגן אַ נייַע זייַל "פרייַנד שייַן" => אָ(1)
  • טשאַנגינג דאַטן: דיליטינג אַ פרייַנד: נאָר אַראָפּנעמען די פריינד שייַן זייַל => אָ (1)

Как видим, существенным преимуществом такой модели хранения является то, что мы во всех необходимых нам сценариях оперируем только одной колонкой, избегая вычитывания из базы всей строки и тем более, перебора всех колонок этой строки. На этом можно было бы остановиться, но…

איר קענען זיין פּאַזאַלד און גיין אַ ביסל ווייַטער אויף דעם וועג פון אָפּטימיזינג פאָרשטעלונג און רידוסינג י / אָ אַפּעריישאַנז ווען אַקסעס די דאַטאַבייס. וואָס אויב מיר סטאָרד די גאַנץ שייכות אינפֿאָרמאַציע גלייַך אין די רודערן שליסל זיך? אַז איז, מאַכן די שליסל קאַמפּאַזאַט ווי userID.friendID? אין דעם פאַל, מיר טאָן ניט אפילו האָבן צו לייענען די שפאלטן פון די שורה אין אַלע (אָפּציע 4 (רודערן)):

RowKey
ספּיקערז

Вася.Петя
פעטיאַ: 1

וואַסיאַ.אָליאַ
אָליאַ: 1

וואַסיאַ.דאַשאַ
דאַשאַ: 1

Петя.Маша
מאַשאַ: 1

פּעטיאַ.וואַסיאַ
וואַסיאַ: 1

דאָך, די אַסעסמאַנט פון אַלע דאַטן מאַניפּיאַליישאַן סינעריאָוז אין אַזאַ אַ סטרוקטור, ווי אין די פריערדיקע ווערסיע, וועט זיין אָ (1). דער חילוק מיט אָפּציע 3 וועט זיין בלויז אין די עפעקטיווקייַט פון י / אָ אַפּעריישאַנז אין די דאַטאַבייס.

נו, די לעצטע "בויגן". עס איז גרינג צו זען אַז אין אָפּציע 4, די רודערן שליסל וועט האָבן אַ בייַטעוודיק לענג, וואָס קען עפשער ווירקן פאָרשטעלונג (דאָ מיר געדענקען אַז HBase סטאָרז דאַטן ווי אַ סכום פון ביטעס און ראָוז אין טישן זענען אויסגעשטעלט דורך שליסל). פּלוס מיר האָבן אַ סעפּאַראַטאָר וואָס קען זיין כאַנדאַלד אין עטלעכע סינעריאָוז. צו עלימינירן דעם השפּעה, איר קענען נוצן האַשעס פֿון UserID און friendID, און זינט ביידע האַשעס האָבן אַ קעסיידערדיק לענג, איר קענען פשוט קאַנקאַטאַנייט זיי אָן אַ סעפּאַראַטאָר. דערנאָך די דאַטן אין די טיש וועט קוקן ווי דאָס (Вариант 5(hash)):

RowKey
ספּיקערז

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
פעטיאַ: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
אָליאַ: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
דאַשאַ: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
מאַשאַ: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
וואַסיאַ: 1

דאָך, די אַלגערידאַמיק קאַמפּלעקסיטי פון ארבעטן מיט אַזאַ אַ סטרוקטור אין די סינעריאָוז וואָס מיר באַטראַכטן וועט זיין די זעלבע ווי די פון אָפּציע 4 - דאָס איז אָ (1).
Итого, сведем все наши оценки вычислительной сложности в одну таблицу:

אַדינג אַ פרייַנד
טשעק אויף אַ פרייַנד
רימוווינג אַ פרייַנד

Вариант 1 (default)
אָ (N)
אָ (N)
אָ (N)

אָפּציע 2 (ציילן)
אָ (1)
אָ (N)
אָ (N)

אָפּציע 3 (שאָלע)
אָ (1)
אָ (1)
אָ (1)

אָפּציע 4 (רודערן)
אָ (1)
אָ (1)
אָ (1)

Вариант 5 (hash)
אָ (1)
אָ (1)
אָ (1)

ווי איר קענען זען, אָפּציעס 3-5 ויסקומען צו זיין די מערסט בילכער און טהעאָרעטיקאַללי ינשור די דורכפירונג פון אַלע נייטיק דאַטן מאַניפּיאַליישאַן סינעריאָוז אין קעסיידערדיק צייט. אין די באדינגונגען פון אונדזער אַרבעט, עס איז קיין יקספּליסאַט פאָדערונג צו קריגן אַ רשימה פון אַלע די פרענדז פון די באַניצער, אָבער אין פאַקטיש פּרויעקט אַקטיוויטעטן, עס וואָלט זיין גוט פֿאַר אונדז, ווי גוט אַנאַליס, צו "ריכטן" אַז אַזאַ אַ אַרבעט קען אויפשטיין און "שפּרייט אַ שטרוי." דעריבער, מיין סימפּאַטי איז אויף די זייַט פון אָפּציע 3. אָבער עס איז גאַנץ מסתּמא אַז אין אַ פאַקטיש פּרויעקט דעם בקשה האט שוין סאַלווד דורך אנדערע מיטלען, דעריבער, אָן אַ גענעראַל זעאונג פון די גאנצע פּראָבלעם, עס איז בעסער נישט צו מאַכן לעצט קאַנקלוזשאַנז.

צוגרייטונג פון דער עקספּערימענט

Вышеизложенные теоретические рассуждения хотелось бы проверить на практике – это и было целью возникшей на долгих выходных задумки. Для этого необходимо оценить скорость работы нашего «условного приложения» во всех описанных сценариях использования базы, а также рост этого времени с ростом размера социальной сети (n). Целевым параметром, который нас интересует и который мы будем замерять в ходе эксперимента, является время, затраченное «условным приложением», на выполнение одной «бизнес-операции». Под «бизнес-операцией» мы понимаем одну из следующих:

  • אַדינג איין נייַ פרייַנד
  • טשעק אויב באַניצער א איז אַ פרייַנד פון באַניצער ב
  • רימוווינג איין פרייַנד

אַזוי, גענומען אין חשבון די רעקווירעמענץ אַוטליינד אין דער ערשט ויסזאָגונג, די וועראַפאַקיישאַן סצענאַר ימערדזשד ווי גייט:

  • דאַטן רעקאָרדינג. ראַנדאַמלי דזשענערייט אַן ערשט נעץ פון גרייס n. צו באַקומען נעענטער צו דער "פאַקטיש וועלט", די נומער פון פרענדז וואָס יעדער באַניצער האט איז אויך אַ טראַפ - בייַטעוודיק. מעסטן די צייט בעשאַס וואָס אונדזער "קאַנדישאַנאַל אַפּלאַקיישאַן" שרייבט אַלע דזשענערייטאַד דאַטן צו HBase. דערנאָך טיילן די ריזאַלטינג צייט דורך די גאַנץ נומער פון צוגעלייגט פרענדז - דאָס איז ווי מיר באַקומען די דורכשניטלעך צייט פֿאַר איין "געשעפט אָפּעראַציע"
  • לייענען דאַטן. פֿאַר יעדער באַניצער, מאַכן אַ רשימה פון "פערזענלעכקייטן" פֿאַר וואָס איר דאַרפֿן צו באַקומען אַן ענטפער צי דער באַניצער איז אַבאָנירן צו זיי אָדער נישט. די לענג פון דער רשימה = בעערעך די נומער פון פרענדז פון די באַניצער, און פֿאַר האַלב פון די אָפּגעשטעלט פרענדז די ענטפער זאָל זיין "יאָ", און פֿאַר די אנדערע העלפט - "ניין". די טשעק איז דורכגעקאָכט אין אַזאַ סדר אַז די ענטפֿערס "יאָ" און "ניין" בייַטנ לויט דער ריי (דאָס איז, אין יעדער רגע פאַל, מיר וועלן האָבן צו גיין דורך אַלע די שפאלטן פון די שורה פֿאַר אָפּציעס 1 און 2). די גאַנץ זיפּונג צייט איז צעטיילט דורך די נומער פון פרענדז טעסטעד צו באַקומען די דורכשניטלעך זיפּונג צייט פּער טעמע.
  • דיליטינג דאַטן. אַראָפּנעמען אַלע פרענדז פון די באַניצער. דערצו, די דילישאַן סדר איז טראַפ (דאָס איז, מיר "שאַרן" די אָריגינעל רשימה געניצט צו רעקאָרדירן די דאַטן). די גאַנץ טשעק צייט איז דאַן צעטיילט דורך די נומער פון פריינט אַוועקגענומען צו באַקומען די דורכשניטלעך צייט פּער טשעק.

די סינעריאָוז דאַרפֿן צו זיין לויפן פֿאַר יעדער פון די 5 דאַטן מאָדעל אָפּציעס און פֿאַר פאַרשידענע סיזעס פון די געזעלשאַפטלעך נעץ צו זען ווי צייט ענדערונגען ווען עס וואקסט. אין איין n, קאַנעקשאַנז אין די נעץ און די רשימה פון ניצערס צו קאָנטראָלירן מוזן, פון קורס, זיין די זעלבע פֿאַר אַלע 5 אָפּציעס.
פֿאַר אַ בעסער פארשטאנד, אונטן איז אַ ביישפּיל פון דזשענערייטאַד דאַטן פֿאַר n= 5. דער געשריבן "גענעראַטאָר" טראגט דריי שייַן דיקשאַנעריז ווי רעזולטאַט:

  • דער ערשטער איז פֿאַר ינסערשאַן
  • די רגע איז פֿאַר קאָנטראָלירונג
  • דריט - פֿאַר דילישאַן

{0: [1], 1: [4, 5, 3, 2, 1], 2: [1, 2], 3: [2, 4, 1, 5, 3], 4: [2, 1]} # всего 15 друзей

{0: [1, 10800], 1: [5, 10800, 2, 10801, 4, 10802], 2: [1, 10800], 3: [3, 10800, 1, 10801, 5, 10802], 4: [2, 10800]} # всего 18 проверяемых субъектов

{0: [1], 1: [1, 3, 2, 5, 4], 2: [1, 2], 3: [4, 1, 2, 3, 5], 4: [1, 2]} # всего 15 друзей

ווי איר קענען זען, אַלע IDs העכער ווי 10 אין דעם ווערטערבוך פֿאַר קאָנטראָלירונג זענען פּונקט די וואָס וועט זיכער געבן די ענטפער פאַלש. ינסערטינג, קאָנטראָלירונג און ויסמעקן "פריינט" זענען דורכגעקאָכט פּונקט אין די סיקוואַנס ספּעסיפיעד אין דעם ווערטערבוך.

דער עקספּערימענט איז געווען דורכגעקאָכט אויף אַ לאַפּטאַפּ מיט Windows 10, ווו HBase איז פליסנדיק אין איין דאָקקער קאַנטיינער, און פּיטהאָן מיט דזשופּיטער נאָוטבוק איז פליסנדיק אין די אנדערע. דאָקער איז געווען אַלאַקייטיד קסנומקס קפּו קאָרעס און קסנומקס גיגאבייט פון באַראַן. אַלע די לאָגיק, ווי די עמיאַליישאַן פון די "קאַנדישאַנאַל אַפּלאַקיישאַן" און די "ריפּינג" פֿאַר דזשענערייטינג פּרובירן דאַטן און מעסטן צייט, איז געווען געשריבן אין פּיטהאָן. די ביבליאָטעק איז געניצט צו אַרבעטן מיט HBase happybase, צו רעכענען האַשעס (MD5) פֿאַר אָפּציע 5 - hashlib

גענומען אין חשבון די קאַמפּיוטינג מאַכט פון אַ באַזונדער לאַפּטאַפּ, אַ קאַטער פֿאַר n = 10, 30, ... איז יקספּערמענאַלי אויסגעקליבן. 170 - ווען די גאַנץ אַפּערייטינג צייט פון די פול טעסטינג ציקל (אַלע סינעריאָוז פֿאַר אַלע אָפּציעס פֿאַר אַלע n) איז געווען אפילו מער אָדער ווייניקער גלייַך און פּאַסיק בעשאַס איין טיי פּאַרטיי (אין דורכשניטלעך 15 מינוט).

דאָ עס איז נייטיק צו מאַכן אַ באַמערקונג אַז אין דעם עקספּערימענט מיר זענען נישט בפֿרט אָפּשאַצן אַבסאָלוט פאָרשטעלונג פיגיערז. אפילו אַ קאָרעוו פאַרגלייַך פון פאַרשידענע צוויי אָפּציעס קען נישט זיין גאָר ריכטיק. איצט מיר זענען אינטערעסירט אין די נאַטור פון די ענדערונג אין צייט דיפּענדינג אויף n, זינט גענומען אין חשבון די אויבן קאַנפיגיעריישאַן פון די "פּרובירן שטיין", עס איז זייער שווער צו באַקומען צייט עסטאַמאַץ "קלאָרעד" פון דער השפּעה פון טראַפ און אנדערע סיבות ( און אַזאַ אַרבעט איז נישט באַשטימט).

עקספּערימענט רעזולטאַט

דער ערשטער פּראָבע איז ווי די צייט פארבראכט צו פּלאָמבירן די פרענדז רשימה ענדערונגען. דער רעזולטאַט איז אין די גראַפיק אונטן.
פֿעיִקייטן פון דיזיינינג אַ דאַטן מאָדעל פֿאַר NoSQL
אָפּציעס 3-5, ווי דערוואַרט, ווייַזן אַ כּמעט קעסיידערדיק "געשעפט טראַנסאַקטיאָן" צייט, וואָס טוט נישט אָפענגען אויף די וווּקס פון די נעץ גרייס און אַן ינדיסטינגגווישאַבאַל חילוק אין פאָרשטעלונג.
אָפּציע 2 אויך ווייזט קעסיידערדיק, אָבער אַ ביסל ערגער פאָרשטעלונג, כּמעט פּונקט 2 מאל קאָרעוו צו אָפּציעס 3-5. און דאָס קען נישט אָבער פרייען, ווייַל עס קאָראַלייץ מיט טעאָריע - אין דעם ווערסיע די נומער פון I/O אַפּעריישאַנז צו / פֿון HBase איז פּונקט 2 מאל גרעסער. דאָס קען דינען ווי ומדירעקט זאָגן אַז אונדזער פּראָבע באַנק, אין פּרינציפּ, גיט גוט אַקיעראַסי.
אָפּציע 1 אויך, ווי דערוואַרט, טורנס אויס צו זיין די סלאָואַסט און דעמאַנסטרייץ אַ לינעאַר פאַרגרעסערן אין די צייט פארבראכט אויף אַדינג איינער דעם אנדערן צו די גרייס פון דער נעץ.
זאל ס איצט קוק בייַ די רעזולטאַטן פון די רגע פּראָבע.
פֿעיִקייטן פון דיזיינינג אַ דאַטן מאָדעל פֿאַר NoSQL
אָפּציעס 3-5 ווידער ביכייוו ווי דערוואַרט - קעסיידערדיק צייט, פרייַ פון די גרייס פון דער נעץ. אָפּציעס 1 און 2 באַווייַזן אַ לינעאַר פאַרגרעסערן אין צייט ווען די נעץ גרייס ינקריסיז און ענלעך פאָרשטעלונג. דערצו, אָפּציע 2 טורנס אויס צו זיין אַ ביסל סלאָוער - משמעות רעכט צו דער נויט צו קאָרעקטאָר און פּראָצעס די נאָך "ציילן" זייַל, וואָס ווערט מער באמערקט ווי n וואקסט. אָבער איך וועל זיך נאָך אָפּהאַלטן פון צייכענען קיין אויספירן, ווייל די אַקיעראַסי פון דעם פאַרגלייַך איז לעפיערעך נידעריק. אין דערצו, די ריישיאָוז (וואָס אָפּציע, 1 אָדער 2, איז פאַסטער) טשיינדזשד פון לויפן צו לויפן (בשעת האַלטן די נאַטור פון די אָפענגיקייַט און "גיין האַלדז און האַלדז").

נו, די לעצטע גראַפיק איז דער רעזולטאַט פון באַזייַטיקונג טעסטינג.

פֿעיִקייטן פון דיזיינינג אַ דאַטן מאָדעל פֿאַר NoSQL

ווידער, קיין סאַפּרייזיז דאָ. אָפּציעס 3-5 דורכפירן באַזייַטיקונג אין קעסיידערדיק צייט.
דערצו, ינטערעסטינגלי, אָפּציעס 4 און 5, ניט ענלעך די פריערדיקע סינעריאָוז, ווייַזן אַ ביסל ערגער פאָרשטעלונג ווי אָפּציע 3. משמעות, די רודערן דילישאַן אָפּעראַציע איז מער טייַער ווי די זייַל דילישאַן אָפּעראַציע, וואָס איז בכלל לאַדזשיקאַל.

Варианты 1 и 2, ожидаемо, демонстрируют линейный рост времени. При этом вариант 2 стабильно медленнее варианта 1 – из-за дополнительной операции ввода-вывода по «обслуживанию» колонки count.

Общие выводы эксперимента:

  • אָפּציעס 3-5 באַווייַזן אַ גרעסערע עפעקטיווקייַט ווי זיי נוצן HBase; דערצו, זייער פאָרשטעלונג איז דיפערז מיט אַ קעסיידערדיק קאָרעוו צו יעדער אנדערער און טוט נישט אָפענגען אויף די גרייס פון דער נעץ.
  • דער חילוק צווישן אָפּציעס 4 און 5 איז נישט רעקאָרדעד. אָבער דאָס טוט נישט מיינען אַז אָפּציע 5 זאָל ניט זיין געוויינט. עס איז מסתּמא אַז די יקספּערמענאַל סצענאַר געניצט, גענומען אין חשבון די פאָרשטעלונג קעראַקטעריסטיקס פון די פּראָבע באַנק, האט נישט לאָזן עס צו זיין דיטעקטאַד.
  • די נאַטור פון די פאַרגרעסערן אין די צייט פארלאנגט צו דורכפירן "געשעפט אַפּעריישאַנז" מיט דאַטן בכלל באשטעטיקט די פריער באקומען טעאָרעטיש חשבונות פֿאַר אַלע אָפּציעס.

עפּילאָג

די גראָב יקספּעראַמאַנץ וואָס זענען דורכגעקאָכט זאָל ניט זיין גענומען ווי אַ אַבסאָלוט אמת. עס זענען פילע סיבות וואָס זענען נישט גענומען אין חשבון און פאַרקרימט די רעזולטאַטן (די פלאַקטשויישאַנז זענען ספּעציעל קענטיק אין די גראַפס מיט אַ קליין נעץ גרייס). צום ביישפּיל, די גיכקייַט פון שפּאַנונג, וואָס איז געניצט דורך Happybase, די באַנד און אופֿן פון ימפּלאַמענינג די לאָגיק וואָס איך געשריבן אין פּיטהאָן (איך קען נישט פאָדערן אַז די קאָד איז אָפּטימאַללי געשריבן און יפעקטיוולי געוויינט די קייפּאַבילאַטיז פון אַלע קאַמפּאָונאַנץ), טאָמער. די פֿעיִקייטן פון HBase קאַטשינג, הינטערגרונט טעטיקייט פון Windows 10 אויף מיין לאַפּטאַפּ, עטק. אין אַלגעמיין, מיר קענען יבערנעמען אַז אַלע טעאָרעטיש חשבונות האָבן יקספּערמענאַלי דעמאַנסטרייטיד זייער גילטיקייַט. נו, אָדער לפּחות עס איז געווען ניט מעגלעך צו אָפּזאָגן זיי מיט אַזאַ אַ "קאָפּ-אויף באַפאַלן".

В заключении — рекомендации всем, кто только начинает проектировать модели данных в HBase: абстрагируйтесь от предыдущего опыта работы с реляционными базами и помните «заповеди»:

  • ווען דיזיינינג, מיר גיינ ווייַטער פון די אַרבעט און פּאַטערנז פון דאַטן מאַניפּיאַליישאַן, און נישט פֿון די פעלד מאָדעל
  • עפעקטיוו אַקסעס (אָן פול טיש יבערקוקן) - בלויז דורך שליסל
  • Денормализация
  • פאַרשידענע ראָוז קענען אַנטהאַלטן פאַרשידענע שפאלטן
  • דינאַמיש זאַץ פון ספּיקערז

מקור: www.habr.com

לייגן אַ באַמערקונג