На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Внимательно изучите правила раздела перед созданием темы
0. ПРИЛАГАЙТЕ СВОИ СКРИПТЫ.
1. Прежде чем создать топик, используйте поиск. Возможно это уже обсуждалось.
2. В топике указывайте ОС, режим работы скрипта (CLI|CGI). Очень желателен вывод лог-файлов и того места, куда у вас назначен вывод данных (STDOUT|STDERR)
3. Помните: вы знаете что вы хотите, а форумчане - нет. Поэтому следуйте простому правилу: грамотный развернутый вопрос - грамотный развернутый ответ.
Модераторы: ANDLL
  
    > Шпаргалка по многопоточности и работе с PostgreSQL
      В соседней теме наваял небольшой бэйнчмарк по тестированию записи логов в БД. Захотелось это реализовать на Perl'е.
      Оставлю тут код, может быть кто-то чего-то найдет для себя интересного:

      ExpandedWrap disabled
        #!/usr/bin/perl -w
         
        # Подключаем библиотеки
        use Time::HiRes qw(gettimeofday);
        use threads;
        use threads::shared;
        use DBI;
         
        # список создаваемых URL
        @URLs = ();
        @Req = ();
        # реквизиты БД
        $DBName   = "testo";
        $UserName = "pgsql";
        $DBHost   = "192.168.1.47";
        $DBPort   = "5432";
        # счетчики замеров
        $TimeRaw  = 0;
        $TimeId   = 0;
        $SizeRaw  = 0;
        $SizeId   = 0;
         
         
        ###############################################################################
        $|++; if ($^O =~ /win/i) { system("cls"); } else { system("clear"); }
        print "\nПоехали тестировать ============================================\n\n";
        ###############################################################################
         
        # 1.Генерируем 1000 URL'ов произвольной длины в диапазоне 12...128
        GenerateUrls(\@URLs);
        # 2.Гененируем таблицу запросов (индексы из @URLs)
        GenerateReq(\@Req);
        # 3.Чистим таблицы и записываем "каталог" URLs в БД
        PrepareTables(\@URLs);
        # 4.Запускаем 10 потоков за запись "сырых" логов и засекаем время их исполнения
        ThreadRawFunc();
        # 5.Вызываем вакуум и вычисляем размер полученной таблицы LogsRaw
        $SizeRaw = GatheringStats("LogsRaw");
        # 6.Чистим таблицы и записываем "каталог" URLs в БД
        PrepareTables(\@URLs);
        # 7.Запускаем 10 потоков за запись "нормализованных" логов
        ThreadIdFunc();
        # 8.Вызываем вакуум и вычисляем размер полученной таблицы LogsId
        $SizeId = GatheringStats("LogsId");
        # 9.Отчет
        print "\n Время записи RAW-логов: $TimeRaw сек (полученный размер: $SizeRaw Mb)\n Время записи \"нормализованных\"-логов: $TimeId сек (полученный размер: $SizeId Mb)\n\n";
         
        ###############################################################################
         
        sub GenerateUrls {
          print " * Генерируем URL'ы ... ";
          my $Array = shift;
          srand();
          for my $I (1..1000) {
            my $S = "";
            for my $J (0..rand(244)+11) {    
              $S .= chr(ord('a')+rand(ord('z')-ord('a')));
            }
            push @{$Array}, $S;
          }
          print "Ok\n";
        }
         
        sub GenerateReq {
          print " * Генерируем произвольный массив индексов запросов URLs ... ";
          my $Array = shift;
          srand();
          for my $I (1..100000) {
            push @{$Array}, int(rand(999));
          }
          print "Ok\n";
        }
         
        sub PrepareTables {
          my $Array = shift;
          my $Dbh = DBI->connect("dbi:Pg:dbname=$DBName;host=$DBHost;port=$DBPort","$UserName","",{PrintError => 0});
          die "$DBI::errstr\n" if (defined($DBI::err));
          # -- чистим таблицу URL
          print "\n * Подготавливаем БД:\n";
          print "   - чистим таблицу URLs ... ";
          my $query = "DELETE FROM \"URLs\"";
          my $sth = $Dbh->prepare($query);
          my $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          print "Ok\n";
          # -- чистим таблицу LogsRaw
          print "   - чистим таблицу LogRaw ... ";
          $query = "DELETE FROM \"LogsRaw\"";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          print "Ok\n";
          # -- чистим таблицу LogsId
          print "   - чистим таблицу LogId ... ";
          $query = "DELETE FROM \"LogsId\"";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          print "Ok\n";
          # -- сбрасываем счетчики Id таблиц
          print "   - сбрасываем счетчики Id таблиц ... ";
          $query = "ALTER SEQUENCE public.\"URLs_Id_seq\" INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 RESTART 1 CACHE 1 NO CYCLE";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          $query = "ALTER SEQUENCE public.\"LogsId_Id_seq\" INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 RESTART 1 CACHE 1 NO CYCLE";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          $query = "ALTER SEQUENCE public.\"Logs_Id_seq\" INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 RESTART 1 CACHE 1 NO CYCLE";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          print "Ok\n";
          # -- вакуум
          print "   - вакуум + сбор статистики ... ";
          $query = "VACUUM FULL ANALYZE";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          print "Ok\n";
          # -- заполняем таблицу URLs
          print "   - запоняем таблицу URLs ... ";
          $query = "INSERT INTO \"URLs\" (\"URL\") VALUES ";
          for(my $I=0; $I<scalar(@{$Array}); $I++) {
            $query.="('".${$Array}[$I]."')";
            $query.= ", " if ($I+1<scalar(@{$Array}));  
          }
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          print "Ok\n";
          # -- переиндексируем таблицу URL
          print "   - переиндексируем таблицу URLs ... ";
          $query = "REINDEX TABLE \"URLs\"";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          $Dbh->disconnect();
          print "Ок\n   - пауза 30 сек ... ";
          sleep(30);
          print "Ok\n\n";
        }
         
        sub ThreadRawFunc {
          print " * Записываем LogsRaw ";
          my @Threads;
          my $Threads=10;
          # Создаём нужное количество потоков
          for my $T (1..$Threads) {
            push @Threads, threads->create(\&WriteLogsRaw, $T);
          }
          # Дожидаемся окончания работы всех потоков
          my $Start = gettimeofday;
          foreach my $T (@Threads) {
            $T->join();
          }
          $TimeRaw = gettimeofday() - $Start;
          print " Ok\n";
        }
         
        sub ThreadIdFunc {
          print " * Записываем LogsId ";
          my @Threads;
          my $Threads=10;
          # Создаём нужное количество потоков
          for my $T (1..$Threads) {
            push @Threads, threads->create(\&WriteLogsId, $T);
          }
          # Дожидаемся окончания работы всех потоков
          my $Start = gettimeofday;
          foreach my $T (@Threads) {
            $T->join();
          }
          $TimeId = gettimeofday() - $Start;
          print " Ok\n";
        }
         
        sub WriteLogsRaw {
          print ".";
          my $Dbh = DBI->connect("dbi:Pg:dbname=$DBName;host=$DBHost;port=$DBPort","$UserName","",{PrintError => 0});
          die "$DBI::errstr\n" if (defined($DBI::err));
          foreach my $I (@{Req}) {
            my $query = "INSERT INTO \"LogsRaw\" (\"URL\",\"Timestamp\") VALUES ('".$URLs[$I]."', NOW())";
            my $sth = $Dbh->prepare($query);
            my $rv = $sth->execute();
            die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          }
          $Dbh->disconnect();
        }
         
        sub WriteLogsId {
          print ".";
          my $Dbh = DBI->connect("dbi:Pg:dbname=$DBName;host=$DBHost;port=$DBPort","$UserName","",{PrintError => 0});
          die "$DBI::errstr\n" if (defined($DBI::err));
          foreach my $I (@{Req}) {
            my $query = "INSERT INTO \"LogsId\" (\"IdUrl\",\"Timestamp\") VALUES ((SELECT u.\"Id\" FROM \"URLs\" AS u WHERE u.\"URL\" = '".$URLs[$I]."'), NOW())";
            my $sth = $Dbh->prepare($query);
            my $rv = $sth->execute();
            die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          }
          $Dbh->disconnect();
        }
         
        sub GatheringStats {
          my $Name = shift;
          print " * Поизводим вакуум и вычисляем размер таблицы \"".$Name."\" ... ";
          my $Dbh = DBI->connect("dbi:Pg:dbname=$DBName;host=$DBHost;port=$DBPort","$UserName","",{PrintError => 0});
          die "$DBI::errstr\n" if (defined($DBI::err));
          my $query = "VACUUM FULL ANALYZE";
          my $sth = $Dbh->prepare($query);
          my $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          $query = "SELECT (relpages * 8192 / (1024*1024))::int as size_mb FROM pg_class WHERE relname LIKE '".$Name."'";
          $sth = $Dbh->prepare($query);
          $rv = $sth->execute();
          die "Error query on \"$query\": " . $Dbh->errstr . "\n" unless(defined $rv);
          my @array = $sth->fetchrow_array();
          $sth->finish();
          $Dbh->disconnect();
          print " Ok\n";
          return $array[0];
        }
        Ошибка в 13й строке... Под разные задачи и разные ответы. Вряд ли чем-то поможет.
          Чепуху какую-то несешь. Там просто задается имя тестовой базы данных.
            Цитата Majestio @
            Чепуху какую-то несешь. Там просто задается имя тестовой базы данных.

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

            При обработке высоких нагрузок разными способами для каждой задачи всегда приходится придумывать свой подход или пересматривать существующий. Поэтому бесполезно пользоваться шаблонами. Тем более, не проверено, насколько эффективен предложенный и для какой задачи.

            Добавлено
            Вот, вам-там важно до сих пор самоутверждение, а у меня на ночь задача: контроллер. Толку от приведённого кода ни какого не получу. Потому что есть специфика.
            И заново буду искать разные готовые решения или создам своё или всё вместе.

            "Шпаргалка по потокам" находится в гугле. Если конкретно про Perl, то про Perl. А дальше всегда - ясное чистое небо и изнурительная отладка.
            Сообщение отредактировано: Tishaishii -
              Цитата Tishaishii @
              Ошибка в 13й строке...

              А это что? :blink:
              Да и вообще, прежде чем делать выводы, наверное стоило бы посмотреть для чего это писалось, и что тестировалось.
                Выводы уже сделаны.
                  "Ошибка в 13й строке" - это давно устоявшееся жаргонное выражение.
                  Спорить из-за него нет никакого смысла.
                  И тем более устраивать рейтинговые войны!
                  Ей-богу, как дети малые...
                    Цитата vot @
                    "Ошибка в 13й строке" - это давно устоявшееся жаргонное выражение.

                    А по факту - пафосное дерьмо. Жаль.
                      Цитата vot @
                      "Ошибка в 13й строке" - это давно устоявшееся жаргонное выражение.

                      [душниламод]В 17-й[/душниламод]
                        Цитата vot @
                        "Ошибка в 13й строке" - это давно устоявшееся жаргонное выражение.
                        Спорить из-за него нет никакого смысла.
                        И тем более устраивать рейтинговые войны!
                        Ей-богу, как дети малые...

                        Сорян! Походу чел решил заюзать AI типа ChatGPT. Вижу еще одного в разделе С++ MaIron с "внезапным вниманием" к старым постам. Там нужно просто посмотреть конкретику ответов.
                        Валера, теряешь хватку! :lol: Илон Макс не зря начал предупреждать ... Ага рассказывай AI про недопустимость рейтинговых воин ))))
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0409 ]   [ 16 queries used ]   [ Generated: 28.03.24, 21:00 GMT ]