Skip to content

Commit 849b751

Browse files
authored
Merge pull request #4430 from Roardom/wikis
(Add) Move server administration documentation into repo
2 parents 306cd7a + 2f59a57 commit 849b751

9 files changed

+1584
-0
lines changed

Diff for: docs/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Wiki
2+
3+
This wiki serves as the central resource for setting up, managing, and optimising your UNIT3D installation. Whether you're working on local development, managing a production server, or contributing to the open-source community, you'll find a number of useful guides here.

Diff for: docs/basic_tuning.md

+326
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
# Basic Tuning
2+
3+
> [!IMPORTANT]
4+
> These guides are intended for UNIT3D v8.0.0 + instances. While these are better than defaults be careful blindly following them. Proper tuning requires understanding your server, running tests and monitoring the results.
5+
6+
## Redis Single Server
7+
8+
| Category | Severity | Time To Fix |
9+
| ------------- |:----------:| ------------:|
10+
| :rocket: Performance | Major | 30 minutes |
11+
12+
### Introduction
13+
14+
If your Redis service is running on your web server, it is highly recommended that you use **Unix sockets** instead of **TCP ports** to communicate with your web server.
15+
16+
Based on the Redis official benchmark, you can **improve performance by upto 50%** using unix sockets (versus TCP ports) on Redis.
17+
18+
Of course, unix sockets can only be used if both your Laravel application and Redis are running on the same server.
19+
20+
### How To Enable Unix Sockets
21+
22+
First, create the redis folder that the unix socket will be in and set appropriate permissions:
23+
24+
```bash
25+
sudo mkdir -p /var/run/redis/
26+
sudo chown -R redis:www-data /var/run/redis
27+
sudo usermod -aG redis www-data
28+
```
29+
30+
Next, add the unix socket path and permissions in your Redis configuration file (typically at `/etc/redis/redis.conf`):
31+
32+
```ini
33+
unixsocket /var/run/redis/redis.sock
34+
unixsocketperm 770
35+
```
36+
37+
Finally, set your corresponding env variables to the socket path as above:
38+
39+
```bash
40+
REDIS_HOST=/var/run/redis/redis.sock
41+
REDIS_PORT=-1
42+
REDIS_SCHEME=unix
43+
```
44+
45+
Ensure that you have your `config/database.php` file refer to the above variables (notice the `scheme` addition below):
46+
47+
```php{7}
48+
'redis' => [
49+
'client' => env('REDIS_CLIENT', 'phpredis'),
50+
51+
'options' => [
52+
'scheme' => env('REDIS_SCHEME', 'tcp'),
53+
],
54+
55+
'default' => [
56+
'url' => env('REDIS_URL'),
57+
'host' => env('REDIS_HOST', '127.0.0.1'),
58+
'password' => env('REDIS_PASSWORD', null),
59+
'port' => env('REDIS_PORT', '6379'),
60+
'database' => env('REDIS_DB', '0'),
61+
],
62+
63+
'cache' => [
64+
'url' => env('REDIS_URL'),
65+
'host' => env('REDIS_HOST', '127.0.0.1'),
66+
'password' => env('REDIS_PASSWORD', null),
67+
'port' => env('REDIS_PORT', '6379'),
68+
'database' => env('REDIS_CACHE_DB', '1'),
69+
],
70+
],
71+
```
72+
73+
Once that's all done simply restart redis.
74+
75+
```bash
76+
sudo systemctl restart redis
77+
```
78+
79+
80+
### References
81+
82+
- [Redis Official Benchmark on Socket vs TCP](https://redis.io/topics/benchmarks)
83+
- [Laravel Documentation on Redis](https://laravel.com/docs/redis)
84+
85+
> [!NOTE]
86+
> Keep in mind that when using unix socket you will now connect to redis-cli in terminal like so: `redis-cli -s /var/run/redis/redis.sock`
87+
88+
89+
## MySQL Single Server
90+
91+
| Category | Severity | Time To Fix |
92+
| ------------- |:----------:| ------------:|
93+
| :rocket: Performance | Major | 10 minutes |
94+
95+
### Introduction
96+
97+
If your MySQL database is running on your web server, it is highly recommended that you use **Unix sockets** instead of **TCP ports** to communicate with your web server.
98+
99+
Based on Percona's benchmark, you can **improve performance by upto 50%** using unix sockets (versus TCP portson MySQL.
100+
101+
Of course, unix sockets can only be used if both your UNIT3D application and database are running on the same server which is by default.
102+
103+
### How To Enable Unix Sockets
104+
105+
First, open your MySQL configuration file.
106+
107+
```bash
108+
nano /etc/mysql/my.cnf
109+
```
110+
111+
Then, uncomment and change (if needed) the socket parameter in the `[mysqld]` section of one of the above configuration files:
112+
113+
```ini
114+
[mysqld]
115+
user = mysql
116+
pid-file = /var/run/mysqld/mysqld.pid
117+
socket = /var/run/mysqld/mysqld.sock
118+
port = 3306
119+
```
120+
121+
Close this file, then ensure that the mysqld.sock file exists by running an ls command on the directory where MySQL expects to find it:
122+
123+
`ls -a /var/run/mysqld/`
124+
125+
If the socket file exists, you will see it in this command’s output:
126+
127+
Output
128+
`. .. mysqld.pid mysqld.sock mysqld.sock.lock`
129+
If the file does not exist, the reason may be that MySQL is trying to create it, but does not have adequate permissions to do so. You can ensure that the correct permissions are in place by changing the directory’s ownership to the mysql user and group:
130+
131+
`sudo chown mysql:mysql /var/run/mysqld/`
132+
133+
Then ensure that the mysql user has the appropriate permissions over the directory. Setting these to 775 will work in most cases:
134+
135+
`sudo chmod -R 755 /var/run/mysqld/`
136+
137+
Finally, set your `database.connections.mysql.unix_socket` configuration variable or the corresponding env variable to the socket path as above:
138+
139+
```bash
140+
DB_SOCKET=/var/run/mysqld/mysqld.sock
141+
```
142+
143+
Once that's all done simply refresh your cache and then restart the services.
144+
145+
```bash
146+
php artisan set:all_cache
147+
```
148+
149+
```bash
150+
sudo systemctl restart mysql && sudo systemctl restart php8.3-fpm && sudo systemctl restart nginx
151+
```
152+
153+
### References
154+
155+
- [Percona Benchmark (Unix vs TCP)](https://www.percona.com/blog/2020/04/13/need-to-connect-to-a-local-mysql-server-use-unix-domain-socket/)
156+
- [MySQL Unix Socket Setup](https://www.digitalocean.com/community/tutorials/how-to-troubleshoot-socket-errors-in-mysql)
157+
- [MySQL Shell Connections Guide](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-connection-socket.html)
158+
159+
## Composer Autoloader Optimization
160+
161+
| Category | Severity | Time To Fix |
162+
| ------------- |:----------:| ------------:|
163+
| :rocket: Performance | Moderate | 5 minutes |
164+
165+
### Introduction
166+
167+
Due to the way PSR-0/4 autoloading rules are defined, the Composer autoloader checks the filesystem before resolving a classname conclusively.
168+
169+
In production, Composer allows for optimization to convert the PSR-0 and PSR-4 autoloading rules into classmap rules, making autoloading quite a bit faster. In production we also don't need all the require-dev dependencies loaded up!
170+
171+
### How To Optimize?
172+
It's really simple. SSH to your server and run the following commands.
173+
```bash
174+
composer install --prefer-dist --no-dev
175+
```
176+
177+
```bash
178+
composer dump-autoload --optimize
179+
```
180+
181+
### References
182+
183+
- https://getcomposer.org/doc/articles/autoloader-optimization.md
184+
185+
## PHP8 OPCache
186+
187+
| Category | Severity | Time To Fix |
188+
| ------------- |:----------:| ------------:|
189+
| :rocket: Performance | Major | 10 minutes |
190+
191+
192+
### Introduction
193+
194+
Opcache provides massive performance gains. One of the benchmarks suggest it can provide a 5.5X performance gain in a Laravel application!
195+
196+
`What is OPcache?`
197+
Every time you execute a PHP script, the script needs to be compiled to byte code. OPCache leverages a cache for this bytecode, so the next time the same script is requested, it doesn’t have to recompile it. This can save some precious execution time, and thus make UNIT3D faster.
198+
199+
`Sounds awesome, so how can you use it?`
200+
Easy. SSH to your server and run the following command. `sudo nano /etc/php/8.3/fpm/php.ini` This is assuming your on PHP 8.3. If not then adjust the command. Once you have the config open search for `opcache`.
201+
202+
Now you can change some values, I will walk you through the most important ones.
203+
204+
`opcache.enable=1`
205+
This of course, enables OPcache for php-fpm. Make sure it is uncommented. AKA remove the`;`
206+
207+
`opcache.enable_cli=1`
208+
This of course, enables OPcache for php-cli. Make sure it is uncommented. AKA remove the`;`
209+
210+
`opcache.memory_consumption=256M`
211+
How many Megabyte you want to assign to OPCache. Choose anything higher than 64 (default value) depending on your needs. 2GB is sufficient but if have more RAM then make use of it! Make sure it is uncommented. AKA remove the`;`
212+
213+
`opcache.interned_strings_buffer=64`
214+
How many Megabyte you want to assign to interned strings. Choose anything higher than 16 (default value). 1GB is sufficient but if have more RAM then make use of it! Make sure it is uncommented. AKA remove the`;`
215+
216+
`opcache.validate_timestamps=0`
217+
This will revalidate the script. If you set this to 0 (best performance), you need to manually clear the OPcache every time your PHP code changes. So if you update UNIT3D using `php artisan git:update` or manually make changes yourself you need to run `sudo systemctl restart php8.2-fpm` afterwords for your changes to take effect and show. Make sure it is uncommented. AKA remove the`;`
218+
219+
`opcache.save_comments=1`
220+
This will preserve comments in your script, I recommend to keep this enabled, as some libraries depend on it, and I couldn’t find any benefits from disabling it (except from saving a few bytes RAM). Make sure it is uncommented. AKA remove the`;`
221+
222+
And there you have it folks. Experiment with these values, depending on the resources of your server. Save the file and exit and restart PHP `sudo systemctl restart php8.3-fpm`.
223+
224+
Enjoy! 🖖
225+
226+
## PHP 8 Preloading
227+
228+
| Category | Severity | Time To Fix |
229+
| ------------- |:----------:| ------------:|
230+
| :rocket: Performance | Major | 5 minutes |
231+
232+
233+
### Introduction
234+
235+
This is chaining off `Want More Performance? Lets talk about OPCache!` guide. You must have OPCache enabled to use preloading.
236+
237+
PHP preloading for PHP >=7.4. Preloading is a feature of php that will pre-compile php functions and classes to opcache. Thus, this becomes available in your programs with out needing to require the files, which improves speed. To read more on php preloading you can see the [opcache.preloading documentation](https://www.php.net/manual/en/opcache.preloading.php).
238+
239+
### Enabling Preloading
240+
241+
SSH to your server and run the following command. `sudo nano /etc/php/8.3/fpm/php.ini` This is assuming your on PHP 8.3. If not then adjust the command. Once you have the config open search for `preload`.
242+
243+
Now you can change some values.
244+
245+
```
246+
; Specifies a PHP script that is going to be compiled and executed at server
247+
; start-up.
248+
; https://php.net/opcache.preload
249+
opcache.preload = '/var/www/html/preload.php';
250+
251+
; Preloading code as root is not allowed for security reasons. This directive
252+
; facilitates to let the preloading to be run as another user.
253+
; https://php.net/opcache.preload_user
254+
opcache.preload_user=ubuntu
255+
```
256+
257+
As you can see we are calling the preload file included in UNIT3D located in `/var/www/html/preload.php`.
258+
`opcache.preload_user=ubuntu` you should changed to your server user. Not root!!!!
259+
260+
And there you have it folks. Save the file and exit and restart PHP `sudo systemctl restart php8.3-fpm`. You are now preloading Laravel thus making UNIT3D faster.
261+
262+
## PHP8 JIT
263+
264+
| Category | Severity | Time To Fix |
265+
| ------------- |:----------:| ------------:|
266+
| :rocket: Performance | Moderate | 5 minutes |
267+
268+
### Introduction
269+
270+
PHP 8 adds a JIT compiler to PHP's core which has the potential to speed up performance dramatically.
271+
272+
First of all, the JIT will only work if opcache is enabled, this is the default for most PHP installations, but you should make sure that `opcache.enable` is set to `1` in your php.ini file. Enabling the JIT itself is done by specifying `opcache.jit_buffer_size` in php.ini. **_So I recommend checking the OPcache guide I made first then coming back here._**
273+
274+
### How To Enable JIT
275+
SSH to your server and run the following command. `sudo nano /etc/php/8.3/fpm/php.ini` This is assuming your on PHP 8.2. If not then adjust the command. Once you have the config open search for `opcache.jit`.
276+
277+
If you do not get any results then search for `[curl]` you should see the following.
278+
279+
```
280+
[curl]
281+
; A default value for the CURLOPT_CAINFO option. This is required to be an
282+
; absolute path.
283+
;curl.cainfo =
284+
```
285+
286+
Right above it add:
287+
288+
```
289+
opcache.jit_buffer_size=256M
290+
```
291+
292+
Its as simple as that. Save and exit and restart PHP. `sudo systemctl restart php8.2-fpm`
293+
294+
## PM Static
295+
296+
| Category | Severity | Time To Fix |
297+
| ------------- |:----------:| ------------:|
298+
| :rocket: Performance | Major | 10 minutes |
299+
300+
> [!IMPORTANT]
301+
> This guide is intended for high traffic sites.
302+
303+
### Introduction
304+
305+
Lets give a basic description on what these options are:
306+
307+
`pm = dynamic` – the number of child processes is set dynamically based on the following directives: pm.max_children, pm.start_servers,pm.min_spare_servers, pm.max_spare_servers.
308+
309+
`pm = ondemand` – the processes spawn on demand (when requested, as opposed to dynamic, where pm.start_servers are started when the service is started.
310+
311+
`pm = static` – the number of child processes is fixed by pm.max_children.
312+
313+
The PHP-FPM pm static setting depends heavily on how much free memory your server has. Basically if you are suffering from low server memory, then pm ondemand or dynamic maybe be better options. On the other hand, if you have the memory available you can avoid much of the PHP process manager (PM) overhead by setting pm static to the max capacity of your server. In other words, when you do the math, pm.static should be set to the max amount of PHP-FPM processes that can run without creating memory availability or cache pressure issues. Also, not so high as to overwhelm CPU(s) and have a pile of pending PHP-FPM operations.
314+
315+
### Enabling Static
316+
317+
Lets open up our PHP configuration file. `sudo nano /etc/php/8.3/fpm/pool.d/www.conf`
318+
319+
Set `pm = static`
320+
Set `pm.max_children = 25`
321+
322+
Save, Exit and Restart `sudo systemctl restart php8.3-fpm`
323+
324+
### Conclusion
325+
326+
When it comes to PHP-FPM, once you start to serve serious traffic, ondemand and dynamic process managers for PHP-FPM can limit throughput because of the inherent overhead. Know your system and set your PHP-FPM processes to match your server’s max capacity.

0 commit comments

Comments
 (0)