Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

Merge pull request #118898 from talyz/gitlab-memory-bloat

nixos/gitlab: Add options to tame GitLab's memory usage somewhat

authored by Kim Lindberger and committed by GitHub fdd6ca8f 445c114b

+115 -3
+115 -3
nixos/modules/services/misc/gitlab.nix
··· 155 155 GITLAB_REDIS_CONFIG_FILE = pkgs.writeText "redis.yml" (builtins.toJSON redisConfig); 156 156 prometheus_multiproc_dir = "/run/gitlab"; 157 157 RAILS_ENV = "production"; 158 + MALLOC_ARENA_MAX = "2"; 158 159 }; 159 160 160 161 gitlab-rake = pkgs.stdenv.mkDerivation { ··· 652 653 description = "Extra configuration to merge into shell-config.yml"; 653 654 }; 654 655 656 + puma.workers = mkOption { 657 + type = types.int; 658 + default = 2; 659 + apply = x: builtins.toString x; 660 + description = '' 661 + The number of worker processes Puma should spawn. This 662 + controls the amount of parallel Ruby code can be 663 + executed. GitLab recommends <quote>Number of CPU cores - 664 + 1</quote>, but at least two. 665 + 666 + <note> 667 + <para> 668 + Each worker consumes quite a bit of memory, so 669 + be careful when increasing this. 670 + </para> 671 + </note> 672 + ''; 673 + }; 674 + 675 + puma.threadsMin = mkOption { 676 + type = types.int; 677 + default = 0; 678 + apply = x: builtins.toString x; 679 + description = '' 680 + The minimum number of threads Puma should use per 681 + worker. 682 + 683 + <note> 684 + <para> 685 + Each thread consumes memory and contributes to Global VM 686 + Lock contention, so be careful when increasing this. 687 + </para> 688 + </note> 689 + ''; 690 + }; 691 + 692 + puma.threadsMax = mkOption { 693 + type = types.int; 694 + default = 4; 695 + apply = x: builtins.toString x; 696 + description = '' 697 + The maximum number of threads Puma should use per 698 + worker. This limits how many threads Puma will automatically 699 + spawn in response to requests. In contrast to workers, 700 + threads will never be able to run Ruby code in parallel, but 701 + give higher IO parallelism. 702 + 703 + <note> 704 + <para> 705 + Each thread consumes memory and contributes to Global VM 706 + Lock contention, so be careful when increasing this. 707 + </para> 708 + </note> 709 + ''; 710 + }; 711 + 712 + sidekiq.memoryKiller.enable = mkOption { 713 + type = types.bool; 714 + default = true; 715 + description = '' 716 + Whether the Sidekiq MemoryKiller should be turned 717 + on. MemoryKiller kills Sidekiq when its memory consumption 718 + exceeds a certain limit. 719 + 720 + See <link xlink:href="https://docs.gitlab.com/ee/administration/operations/sidekiq_memory_killer.html"/> 721 + for details. 722 + ''; 723 + }; 724 + 725 + sidekiq.memoryKiller.maxMemory = mkOption { 726 + type = types.int; 727 + default = 2000; 728 + apply = x: builtins.toString (x * 1024); 729 + description = '' 730 + The maximum amount of memory, in MiB, a Sidekiq worker is 731 + allowed to consume before being killed. 732 + ''; 733 + }; 734 + 735 + sidekiq.memoryKiller.graceTime = mkOption { 736 + type = types.int; 737 + default = 900; 738 + apply = x: builtins.toString x; 739 + description = '' 740 + The time MemoryKiller waits after noticing excessive memory 741 + consumption before killing Sidekiq. 742 + ''; 743 + }; 744 + 745 + sidekiq.memoryKiller.shutdownWait = mkOption { 746 + type = types.int; 747 + default = 30; 748 + apply = x: builtins.toString x; 749 + description = '' 750 + The time allowed for all jobs to finish before Sidekiq is 751 + killed forcefully. 752 + ''; 753 + }; 754 + 655 755 extraConfig = mkOption { 656 756 type = types.attrs; 657 757 default = {}; ··· 993 1093 ] ++ optional (cfg.databaseHost == "") "postgresql.service"; 994 1094 wantedBy = [ "gitlab.target" ]; 995 1095 partOf = [ "gitlab.target" ]; 996 - environment = gitlabEnv; 1096 + environment = gitlabEnv // (optionalAttrs cfg.sidekiq.memoryKiller.enable { 1097 + SIDEKIQ_MEMORY_KILLER_MAX_RSS = cfg.sidekiq.memoryKiller.maxMemory; 1098 + SIDEKIQ_MEMORY_KILLER_GRACE_TIME = cfg.sidekiq.memoryKiller.graceTime; 1099 + SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT = cfg.sidekiq.memoryKiller.shutdownWait; 1100 + }); 997 1101 path = with pkgs; [ 998 1102 postgresqlPackage 999 1103 git ··· 1005 1109 # Needed for GitLab project imports 1006 1110 gnutar 1007 1111 gzip 1112 + 1113 + procps # Sidekiq MemoryKiller 1008 1114 ]; 1009 1115 serviceConfig = { 1010 1116 Type = "simple"; 1011 1117 User = cfg.user; 1012 1118 Group = cfg.group; 1013 1119 TimeoutSec = "infinity"; 1014 - Restart = "on-failure"; 1120 + Restart = "always"; 1015 1121 WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab"; 1016 1122 ExecStart="${cfg.packages.gitlab.rubyEnv}/bin/sidekiq -C \"${cfg.packages.gitlab}/share/gitlab/config/sidekiq_queues.yml\" -e production"; 1017 1123 }; ··· 1145 1251 TimeoutSec = "infinity"; 1146 1252 Restart = "on-failure"; 1147 1253 WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab"; 1148 - ExecStart = "${cfg.packages.gitlab.rubyEnv}/bin/puma -C ${cfg.statePath}/config/puma.rb -e production"; 1254 + ExecStart = concatStringsSep " " [ 1255 + "${cfg.packages.gitlab.rubyEnv}/bin/puma" 1256 + "-e production" 1257 + "-C ${cfg.statePath}/config/puma.rb" 1258 + "-w ${cfg.puma.workers}" 1259 + "-t ${cfg.puma.threadsMin}:${cfg.puma.threadsMax}" 1260 + ]; 1149 1261 }; 1150 1262 1151 1263 };