-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfile.fork_worker.html
108 lines (87 loc) · 8.38 KB
/
file.fork_worker.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no'>
<meta name='apple-touch-fullscreen' content='yes'>
<meta name='apple-mobile-web-app-capable' content='yes'>
<meta name='apple-mobile-web-app-status-bar-style' content='rgba(228,228,228,1.0)'>
<title>File: Fork-Worker Cluster Mode [Experimental] — Puma master</title>
<link rel='stylesheet' type='text/css' href='../css/y_fonts.css' />
<link rel='stylesheet' type='text/css' href='../css/highlight.github.css' />
<link rel='stylesheet' type='text/css' href='../css/y_style.css' />
<link rel='stylesheet' type='text/css' href='../css/y_list.css' />
<link rel='stylesheet' type='text/css' href='../css/y_color.css' />
<script type='text/javascript'>
var pathId = "fork_worker",
relpath = '';
var t2Info = {
CSEP: '.',
ISEP: '#',
NSEP: '::'
};
</script>
<script type='text/javascript' charset='utf-8' src='../js/highlight.pack.js'></script>
<script type='text/javascript' charset='utf-8' src='../js/y_app.js'></script>
</head>
<body>
<svg id='y_wait' class viewBox='0 0 90 90'></svg>
<div id='settings' class='hidden'></div>
<div id='y_list' class='d h'>
<header id='list_header'></header>
<nav id= 'list_nav' class='y_nav l_nav'>
<ul id='list_items'></ul>
</nav>
</div>
<div id='y_toc' class='f h'>
<header id='toc_header'></header>
<nav id= 'toc_nav' class='y_nav t_nav'>
<ol id='toc_items'></ol>
</nav>
</div>
<div id='y_main' tabindex='-1'>
<header id='y_header'>
<div id='y_menu'>
<a id='home_no_xhr' href='/'>Home</a> »
<a href='.'>Puma master</a> »
<a href='_index.html'>Index</a> »
<span class='title'><a id='t2_doc_top' href='#'>File: Fork-Worker Cluster Mode [Experimental] ▲</a></span>
</div>
<a id='list_href' href="class_list.html"></a>
<div id='y_measure_em' class='y_measure'></div>
<div id='y_measure_vh' class='y_measure'></div>
<span id='y_measure_50pre' class='y_measure'><code>123456789_123456789_123456789_123456789_123456789_</code></span>
</header>
<div id='content' class='file'>
<h1>Fork-Worker Cluster Mode [Experimental]</h1>
<p><a href="Puma.html" title="Puma (module)"><code>Puma</code></a> 5 introduces an experimental new cluster-mode configuration option, <code>fork_worker</code> (<code>--fork-worker</code> from the CLI). This mode causes <a href="Puma.html" title="Puma (module)"><code>Puma</code></a> to fork additional workers from worker 0, instead of directly from the master process:</p>
<pre class="code ruby"><code class="ruby"><span class='int'>10000</span> <span class='CHAR'>\</span><span class='id identifier rubyid__'>_</span> <span class='id identifier rubyid_puma'>puma</span> <span class='float'>4.3</span> (<span class='id identifier rubyid_tcp'>tcp</span><span class='symbeg'>:</span><span class='op'>/</span><span class='op'>/</span><span class='float'>0.0</span><span class='op'>:</span><span class='int'>9292</span>) [<span class='id identifier rubyid_puma'>puma</span>]
<span class='int'>10001</span> <span class='CHAR'>\</span><span class='id identifier rubyid__'>_</span> <span class='label'>puma:</span> <span class='id identifier rubyid_cluster'>cluster</span> <span class='id identifier rubyid_worker'>worker</span> <span class='int'>0</span><span class='op'>:</span> <span class='int'>10000</span> [<span class='id identifier rubyid_puma'>puma</span>]
<span class='int'>10002</span> <span class='CHAR'>\</span><span class='id identifier rubyid__'>_</span> <span class='label'>puma:</span> <span class='id identifier rubyid_cluster'>cluster</span> <span class='id identifier rubyid_worker'>worker</span> <span class='int'>1</span><span class='op'>:</span> <span class='int'>10000</span> [<span class='id identifier rubyid_puma'>puma</span>]
<span class='int'>10003</span> <span class='CHAR'>\</span><span class='id identifier rubyid__'>_</span> <span class='label'>puma:</span> <span class='id identifier rubyid_cluster'>cluster</span> <span class='id identifier rubyid_worker'>worker</span> <span class='int'>2</span><span class='op'>:</span> <span class='int'>10000</span> [<span class='id identifier rubyid_puma'>puma</span>]
<span class='int'>10004</span> <span class='CHAR'>\</span><span class='id identifier rubyid__'>_</span> <span class='label'>puma:</span> <span class='id identifier rubyid_cluster'>cluster</span> <span class='id identifier rubyid_worker'>worker</span> <span class='int'>3</span><span class='op'>:</span> <span class='int'>10000</span> [<span class='id identifier rubyid_puma'>puma</span>]</code></pre>
<p>The <code>fork_worker</code> option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages:</p>
<ol>
<li><strong>Compatible with phased restart.</strong> Because the master process itself doesn't preload the application, this mode works with phased restart (<code>SIGUSR1</code> or <code>pumactl phased-restart</code>). When worker 0 reloads as part of a phased restart, it initializes a new copy of your application first, then the other workers reload by forking from this new worker already containing the new preloaded application.</li>
</ol>
<p>This allows a phased restart to complete as quickly as a hot restart (<code>SIGUSR2</code> or <code>pumactl restart</code>), while still minimizing downtime by staggering the restart across cluster workers.</p>
<ol>
<li><strong>'Refork' for additional copy-on-write improvements in running applications.</strong> Fork-worker mode introduces a new <code>refork</code> command that re-loads all nonzero workers by re-forking them from worker 0.</li>
</ol>
<p>This command can potentially improve memory utilization in large or complex applications that don't fully pre-initialize on startup, because the re-forked workers can share copy-on-write memory with a worker that has been running for a while and serving requests.</p>
<p>You can trigger a refork by sending the cluster the <code>SIGURG</code> signal or running the <code>pumactl refork</code> command at any time. A refork will also automatically trigger once, after a certain number of requests have been processed by worker 0 (default 1000). To configure the number of requests before the auto-refork, pass a positive integer argument to <code>fork_worker</code> (e.g., <code>fork_worker 1000</code>), or <code>0</code> to disable.</p>
<h3>Usage Considerations</h3>
<ul>
<li><code>fork_worker</code> introduces a new <code>on_refork</code> configuration hook. If you were using the <code>before_fork</code> hook previously, we generally recommend to copy its logic to <code>on_refork</code>. Note that <code>fork_worker</code> triggers the <code>before_fork</code> configuration hook <em>only</em> when initially forking the master process to worker 0, and triggers the <code>on_refork</code> hook on all subsequent forks from worker 0 to additional workers.</li>
</ul>
<h3>Limitations</h3>
<ul>
<li><p>This mode is still very experimental so there may be bugs or edge-cases, particularly around expected behavior of existing hooks. Please open a [bug report]) if you encounter any issues.</p></li>
<li><p>In order to fork new workers cleanly, worker 0 shuts down its server and stops serving requests so there are no open file descriptors or other kinds of shared global state between processes, and to maximize copy-on-write efficiency across the newly-forked workers. This may temporarily reduce total capacity of the cluster during a phased restart / refork.</p></li>
<li><p>In a cluster with <code>n</code> workers, a normal phased restart stops and restarts workers one by one while the application is loaded in each process, so <code>n-1</code> workers are available serving requests during the restart. In a phased restart in fork-worker mode, the application is first loaded in worker 0 while <code>n-1</code> workers are available, then worker 0 remains stopped while the rest of the workers are reloaded one by one, leaving only <code>n-2</code> workers to be available for a brief period of time. Reloading the rest of the workers should be quick because the application is preloaded at that point, but there may be situations where it can take longer (slow clients, long-running application code, slow worker-fork hooks, etc).</p></li>
</ul>
<div id='footer'></div>
</div> <!-- content -->
</div> <!-- y_main -->
</body>
</html>