Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125832 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 598D61A00BD for <internals@lists.php.net>; Wed, 23 Oct 2024 09:44:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1729676797; bh=J0hMJZ3iZqXl2j0mUK8lyFox2em6xpuDAEXXxODlxUo=; h=From:Date:Subject:To:From; b=Rhzfjpr+R7E64u4k8L4K4OCuIw7jTQQLJ0lkYoNEanm75Xzl//RU96Bxy8uK4qYtj sD+lGsIVceSWfMz0xIVt5pIoEkjBSnb680amY48HlnCRUMNUsQbhG+QnAd7Ma03/Jc Ms2Yi5rqJA0cUMc3e1FosxISGL8SxDnSmIc5jntg0n/gtzSOt4sEX8HUrHophPqGtH XtijxHfpSfcIOPK//y4OsqBvM21v+Y42D8lFewTtF9uE6aoVyMtodK5NOstFGIL/Hz E0302w7eNPbsfq2edPKKoaRLtv67IUwJj0A/4f7fygS4Lj9a8xg0e+ARUqxZe+AllU PFW8qdWWrebVA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 049F6180037 for <internals@lists.php.net>; Wed, 23 Oct 2024 09:46:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: <sam@melroseandco.uk> Received: from mail-ua1-f48.google.com (mail-ua1-f48.google.com [209.85.222.48]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for <internals@lists.php.net>; Wed, 23 Oct 2024 09:46:36 +0000 (UTC) Received: by mail-ua1-f48.google.com with SMTP id a1e0cc1a2514c-851d2a36e6dso390071241.0 for <internals@lists.php.net>; Wed, 23 Oct 2024 02:44:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=melroseandco.uk; s=google; t=1729676651; x=1730281451; darn=lists.php.net; h=content-transfer-encoding:to:subject:message-id:date:from :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Ofg3R7lLc07EKhSSWoOB6F7PpLGDcVcswip9dQIXfqY=; b=b1Axw1JQ+6iROm8E3sW4JTuMHLMRphbc8U7UC/YOysSQeSRmkkobb+rZbKBAm28zTE W6V8OGF010O3vNR0/AiZX71t5RNTpZvxa89Y7B3A+9BLCwlb/46MbKKa4ToYuWLJHH8b 7yaMPDBJrRr0nbu8jnYZZmm/EPN88Ecj/5Cq33UU/v7wIvDmdl4yWcOMopTJR8OVcvRm o+8dvf54qX4K9mrL3wMcq22drY6rjA6L2aOA6+01G/D0sgcMUGea5LGsmRDRSCG/0jC9 X8CQBlG4or/9w2hGZbcR4iVVPXsl8qrnbLiCSg8HdSm7JZt1z62Vtui4vOXpeSPqszqI hc1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729676651; x=1730281451; h=content-transfer-encoding:to:subject:message-id:date:from :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Ofg3R7lLc07EKhSSWoOB6F7PpLGDcVcswip9dQIXfqY=; b=KQ7xmFAhOqYvZ9UHlsIb7tXhbvLDCye3M6Ug+a9Yrk2dAeUKgSN1eA35oMXe8Thxnb 7Jv1uF1+ITt0zzg5EnaE7b+UflO3AIAGPt4Yt01q+i3qJROWgWcII0tTchUCqZTsauQu TsdiWzR4C8xxKDWi4F7FD+f3/2BwscKpYR8/+PbUtQ0GZV5IuYrF2f/nsroIGIEjB82q 0//I69eYM/gli5eUSiZgisde0z7918ywRRRHKYipsHtddFnWj7Y6UKTgcxquKHonWRwb oeH5rinFZeK3FLo+5wanclv6CdR6HjUr1DlazfUhMHxxEs83x1xx8+8pY4H1s+kqNju3 b57g== X-Gm-Message-State: AOJu0YyU6UtATXZxZJcwAS6SmZYYd3OMQmQiZzbQ8lzs6OvxbtDQ5oTx +C6KFVm/fe601SM4eC6F6gAHEWQpB69Ga/R4v5ED6CBEFicHFMj96f0Cdy0NwSouBKWfMHlUkH8 aNP0Y0L33AgrD2bWEizceHY2PKPUgGPlzApXdyK0NgDmM/N7ph8c= X-Google-Smtp-Source: AGHT+IG0D74UUex2lbPraRHShVHcdbFjWZTOfnK/Bemaje9dnc8/cGUUvoeNovfJzhYbJ/a3XPn8V0a3MZA7BIWAS3o= X-Received: by 2002:a05:6122:1794:b0:50a:cbdb:b929 with SMTP id 71dfb90a1353d-50fd0f196cemr1102577e0c.2.1729676650763; Wed, 23 Oct 2024 02:44:10 -0700 (PDT) Precedence: bulk list-help: <mailto:internals+help@lists.php.net list-unsubscribe: <mailto:internals+unsubscribe@lists.php.net> list-post: <mailto:internals@lists.php.net> List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Wed, 23 Oct 2024 10:43:59 +0100 Message-ID: <CAMhsXHy=FLtGWEdvtiS9zD3rTP0SOL=A0=i=606W3o8ArLQzkA@mail.gmail.com> Subject: [PHP-DEV] RFC: Support Read-Only opcache.file_cache for use with Docker To: internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: sam@melroseandco.uk (Samuel Melrose) Hello, Following on from a chat with some very helpful contributors on GitHub (https://github.com/php/php-src/issues/16484), I'd like to request feedback on a change and potentially put it forward as an RFC please. Change Description: The `opcache.file_cache` folder must currently be writable, but I propose a read-only mode (potentially enabled via `opcache.file_cache_read_only=3D1`) that allows the folder to be used for loading files when it isn't writable. `opcache.file_cache_read_only=3D1` will fail unless `opcache.validate_timestamps=3D0` and `opcache.revalidate_freq=3D0`, indicating the code is intended to be read-only. An example PR to achieve this is here: https://github.com/php/php-src/pull/16551 (I'd love some feedback please!). Why?: When building containers (i.e. Docker) that contain both the PHP runtime and application code (that isn=E2=80=99t going to change once built into the container), a lot of CPU cycles are wasted re-warming the opcache every time an instance of the container starts, even though the code will always remain the same. In a large distributed container based platform like Lambda, App Runner, App Engine or Cloud Run, there are significant performance gains & cost savings to be realised by being able to pre-warm the JIT at container build time (i.e. in the CI/CD pipeline), then load it from disk at container startup. It is fairly common on these large container platforms for the entire file-system to be read-only (e.g. Kubernetes `readOnlyRootFilesystem`) as a security hardening measure, which makes using the existing `opcache.file_cache` impossible. Usage: The intended usage for this change is to build the opcache via the CLI in the CI/CD workflow, with something like this: `@php -dopcache.enable_cli=3Dtrue -dopcache.file_cache=3D$(pwd)/opcache -dopcache.file_cache_only=3Dtrue prewarm.php` ```php <?php /** * Composer autoloader... */ $filesToLoad =3D require __DIR__ . '/vendor/composer/autoload_files.php'; // Prevent composer autoloading files... foreach ($filesToLoad as $fileIdentifier =3D> $file) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] =3D true; } require __DIR__ . '/vendor/autoload.php'; $finder =3D (new Symfony\Component\Finder\Finder()) ->files() ->name('/\.php$/') ->ignoreDotFiles(false) ->ignoreVCSIgnored(false) ->exclude([ 'vendor/composer', ]) ->notPath([ 'fuel/core/bootstrap.php', 'fuel/core/vendor/htmlawed/htmlawed.php', ]) ->in(__DIR__); foreach($finder as $file) { $filepath =3D $file->getRealPath(); echo "Compiling file " . $file->getRelativePathname() . " ... " . ( opcache_is_script_cached($filepath) ? 'EXISTS' : ( opcache_compile_file($filepath) ? 'OK' : 'FAIL' ) ) . "\n"; } ``` Then including the `opcache` folder, along with the application code, and the following values in `php.ini` inside the Docker container build: ``` ; Tune opcache opcache.revalidate_freq=3D0 ...other values... ## this below should be true on production opcache.enable_file_override=3Dtrue ## this below should be false on production opcache.validate_timestamps=3Dfalse ; Enable pre-warmed opcache opcache.file_cache=3D/workspace/opcache opcache.file_cache_read_only=3Dtrue opcache.file_cache_consistency_checks=3Dfalse ``` Considerations: Part of the opcache file path when stored on disk is the `zend_system_id`, which from my testing, only stays the same on the exact same build of PHP (and as a result this means if your service is restarting to install a PHP update, the opcache files are no longer valid anyway, but not necessarily a problem with Docker containers that stay static until updated as a whole). Benchmarks: First request without opcache warm'd: ``` $ curl -w "@curl-format.txt" -o /dev/null -s http://localhost:32768/_ah/war= mup time_namelookup: 0.000032s time_connect: 0.000160s time_appconnect: 0.000000s time_pretransfer: 0.000193s time_redirect: 0.000000s time_starttransfer: 0.221376s ---------- time_total: 0.221478s ``` First request with opcache pre-warm'd: ``` $ curl -w "@curl-format.txt" -o /dev/null -s http://localhost:32768/_ah/war= mup time_namelookup: 0.000029s time_connect: 0.000164s time_appconnect: 0.000000s time_pretransfer: 0.000198s time_redirect: 0.000000s time_starttransfer: 0.053059s ---------- time_total: 0.053171s ``` The CPU on the machine I'm testing from is a lot more powerful than the CPU allocation for containers in production (it's lots of small instances that scale horizontally), so I'm expecting the improvement to be even more dramatic there. Struggling to benchmark that properly though, as prod/pre-prod for serverless all has a read-only root FS. ** What does everyone think? Feedback welcome please. **