<?xml version="1.0"?>
<rss version="2.0"><channel><title/><link>https://phoenix.lol/index.php?/blogs/blog/1-fox-blog/</link><description><![CDATA[<p>
	Ну в общем то мой блог.
</p>
]]></description><language>en</language><item><title>&#x410;&#x432;&#x442;&#x43E;&#x43C;&#x430;&#x442;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x43E;&#x435; &#x432;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x438;&#x435; MacMini 2012 &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x432;&#x43E;&#x441;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x43B;&#x435;&#x43D;&#x438;&#x44F; &#x43F;&#x438;&#x442;&#x430;&#x43D;&#x438;&#x44F;</title><link>https://phoenix.lol/index.php?/blogs/entry/24-%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5-%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-macmini-2012-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BF%D0%B8%D1%82%D0%B0%D0%BD%D0%B8%D1%8F/</link><description><![CDATA[<p>
	Столкнулся с интересной проблемой!
</p>

<p>
	У меня есть несколько штук MacMini 2012 с вполне себе годным процессором i5 и 16Gb озу, и трудятся они у меня в составе небольшого Proxmox VE кластера!
</p>

<p>
	Ну с учетом того что железки надежные и вполне себе "апграйдабельные" в них установлено по 2 винта: 1й SSD как правило небольшлго размера, на котором собственно гипервизор Proxmox VE, и второй это m2.nvme 2Tb для файловой системы CEPH.
</p>

<p>
	Так вот столкнулся я с проблемой, что после отключения питания и полной разрядкой моего ИБП, о котором напишу позже (а держит он у меня весь мой комплект железа часов 5-7) маки при подаче на них питания автоматически не включаются!!! Причем перед установкой Proxmox VE естественно стояла MacOS и в ее настройках галку я ставил - "запускать автоматчески после восстановления питания", но после установки Proxmox VE эта настройка слетает!
</p>

<p>
	Так вот собственно решение этой проблемы:
</p>

<p>
	Гипервизор Proxmox VE сделан на базе OS Debian Linux и соответственно решать этот вопрос с MacMini необходимо именно из консоли... Логинимся под root'ом и выполняем следующую команду:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">setpci -s 0:1f.0 0xa4.b=0:1</span></pre>

<p>
	и вуаля... теперь после восстановления питания MacMini будет включаться сам!
</p>
]]></description><guid isPermaLink="false">24</guid><pubDate>Mon, 22 Sep 2025 07:30:45 +0000</pubDate></item><item><title>&#x417;&#x430;&#x449;&#x438;&#x442;&#x430; &#x443;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x441;&#x442;&#x432; Mikrotik &#x43E;&#x442; &#x432;&#x437;&#x43B;&#x43E;&#x43C;&#x430; &#x438;&#x43B;&#x438; &#x441;&#x431;&#x440;&#x43E;&#x441;&#x430; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x435;&#x43A; &#x43F;&#x440;&#x438; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x438; Protected RouterBOOT</title><link>https://phoenix.lol/index.php?/blogs/entry/23-%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B0-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2-mikrotik-%D0%BE%D1%82-%D0%B2%D0%B7%D0%BB%D0%BE%D0%BC%D0%B0-%D0%B8%D0%BB%D0%B8-%D1%81%D0%B1%D1%80%D0%BE%D1%81%D0%B0-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA-%D0%BF%D1%80%D0%B8-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D0%B8-protected-routerboot/</link><description><![CDATA[<p>
	Говоря о безопасности, часто подразумевается безопасность сетевая, связанная с возможным удаленным доступом злоумышленника к устройству. Но не меньшее значение имеет безопасность физическая, когда третьи лица получили или могут получить непосредственный доступ к устройству. Это порождает отдельный набор различных угроз, связанный как с потерей конфигурации устройства, так и получения конфиденциальных данных с него. Поэтому в данной статье мы рассмотрим, как можно противодействовать им с помощью встроенных средств Mikrotik.
</p>

<p>
	Прежде чем настраивать защиту следует понять какие именно действия можно произвести с устройством имея к нему физический доступ. Самое простое - сброс настроек. Это актуально для сетевых устройств, установленных на конечных точках или филиалах, где к ним могут иметь доступ местные администраторы (чаще приходящие) или сотрудники провайдера.
</p>

<p>
	Сбросить устройство можно двумя методами: через кнопку Reset или через Netinstall. В обоих случаях конфигурация будет потеряна, но в случае сброса через Reset сохраняется содержимое внутренней памяти, а там могут находиться сертификаты с закрытыми ключами или выгрузки конфигурации содержащие конфиденциальные сведения, например, пароли.
</p>

<p>
	В данном случае мы получаем две возможные угрозы: несанкционированный сброс конфигурации устройства и возможный доступ к конфиденциальным данным.
</p>

<p>
	Если говорить о целенаправленном взломе, то имеется возможность физического доступа к устройству, можно выполнить понижение прошивки через Netinstall с сохранением конфигурации и последующим взломом через эксплуатацию уязвимости CVE-2018-14847. При этом уязвимости подвержены устройства с версиями RouterOS:
</p>

<ul>
	<li>
		Longterm: 6.30.1 - 6.40.7
	</li>
	<li>
		Stable: 6.29 - 6.42
	</li>
	<li>
		Beta: 6.29rc1 - 6.43rc3
	</li>
</ul>

<p>
	Да, сегодня не все устройства можно откатить на указанные версии прошивки, но все еще очень многие. Для примера взяли два роутера из находящихся у нас в эксплуатации. На один из них, из партии поновее, выполнить атаку на понижение версии ОС уже не получится, а на второй - запросто.
</p>

<p>
	<img alt="Mikrotik-Protected-RouterBOOT-001.png.6f4daeaa4f08e82947a4ea7c6dc4f9c9.png" class="ipsImage ipsImage_thumbnailed" data-fileid="513" data-ratio="116.19" style="height:auto;" width="451" data-src="https://phoenix.lol/uploads/monthly_2025_09/Mikrotik-Protected-RouterBOOT-001.png.6f4daeaa4f08e82947a4ea7c6dc4f9c9.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	Чтобы противодействовать всем возможным попыткам сброса или переустановки RouterOS, не имея административного доступа к роутеру предназначена функция Protected RouterBOOT. Она отключает любой доступ к настройкам конфигурации RouterBOOT через консольный кабель и отключает работу кнопки сброса для изменения режима загрузки (Netinstall также будет отключен). Ее можно включить или выключить только из RouterOS, а если такого доступа нет, то альтернативой становится полное форматирование NAND с последующей чистой установкой RouterOS.
</p>

<p>
	Но и это сделать не так просто, для выполнения сброса нужно удерживать кнопку Reset ровно нужное число секунд и отпустить в указанном интервале, например между 50 и 60 секундами. При этом данный временной интервал можно задать достаточно большим, скажем в несколько минут.
</p>

<p>
	Если вы забыли установленные временные параметры, то сбросить устройство, не зная пароля администратора будет невозможно!
</p>

<p>
	В актуальных версиях RouterOS данные параметры недоступны через графический интерфейс и все настройки выполняются только в терминале.
</p>

<p>
	Прежде всего посмотрим текущие значения:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">/system routerboard settings print</span></pre>

<p>
	По умолчанию установлено следующее:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">protected-routerboot: disabled
 reformat-hold-button: 20s
 reformat-hold-button-max: 10m</span></pre>

<p>
	Разберем их значения подробнее:
</p>

<ul>
	<li>
		<strong>protected-routerboot</strong> - включает режим Protected RouterBOOT, по умолчанию выключено
	</li>
	<li>
		<strong>reformat-hold-button</strong> - указывает необходимое время удержания кнопки сброса для начала форматирования, допустимые значения 5с .. 300с, по умолчанию 20 сек.
	</li>
	<li>
		<strong>reformat-hold-button-max</strong> - указывает максимальное время удержания кнопки сброса для начала форматирования, допустимые значения 15с .. 600с, по умолчанию 10 мин.
	</li>
</ul>

<p>
	Для форматирования устройства нужно удерживать кнопку сброс не менее времени указанного в <strong>reformat-hold-button</strong> и отпустить не позднее чем до времени, указанного в <strong>reformat-hold-button-max</strong>. Минимальное значение между этими параметрами - 10 сек.
</p>

<p>
	Таким образом указав, например, 120 - 130 секунд мы сделаем попытки подбора этого значения крайне затруднительными. Чтобы облегчить подсчет времени Mirotik в этом режиме будет моргать индикатором каждую секунду, т.е. светодиод загорится на 1 секунду и погаснет на следующую.
</p>

<p>
	Перед тем как включать данную функцию следует убедиться, что текущая версия RouterOS не ниже 6.33, а версия Factory Firmware не ниже 3.41. Если это не так, то прошивки надо обновить. Для обновления Factory Firmware воспользуйтесь рекомендациями на официальном сайте:
</p>

<p>
	Для включения защиты выполните:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">/system routerboard settings
set protected-routerboot=enabled
export</span></pre>

<p>
	После чего внимательно изучите вывод команды export, там вы должны увидеть сообщение:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln"># press button within 60 seconds to confirm protected routerboot enable</span></pre>

<p>
	Это означает, что для подтверждения включения Protected RouterBOOT вы должны нажать на кнопку в течении 60 секунд, в противном случае команда будет автоматически отменена.
</p>

<p>
	Данная предосторожность сделана для того, чтобы исключить включение защиты, не располагая физическим доступом к устройству, например, после его взлома.
</p>

<p>
	После чего следует обязательно изменить временные диапазоны для форматирования устройства, со значениями по умолчанию включение защиты не имеет смысла.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">/system routerboard settings
reformat-hold-button=120s 
reformat-hold-button-max=130s</span></pre>

<p>
	Как видим, защитить Mikrotik от возможного несанкционированного доступа третьих лиц не так уж и сложно, однако сам производитель считает данные настройки опасными и поэтому взвешенно подходите к этому вопросу чтобы не создать проблем на ровном месте самому себе.
</p>

<p>
	 
</p>

<p>
	<em>Если вам необходима помощь в настройке Mikrotik напишите <a contenteditable="false" data-ipshover="" data-ipshover-target="https://phoenix.lol/index.php?/profile/1-guy-fawkes/&amp;do=hovercard" data-mentionid="1" href="https://phoenix.lol/index.php?/profile/1-guy-fawkes/" rel="">@Guy Fawkes</a> - помогу решить любую задачу!</em>
</p>
]]></description><guid isPermaLink="false">23</guid><pubDate>Thu, 04 Sep 2025 07:23:17 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C; &#x43B;&#x443;&#x447;&#x448;&#x438;&#x439; VPN &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;?</title><link>https://phoenix.lol/index.php?/blogs/entry/22-%D0%BA%D0%B0%D0%BA-%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D1%82%D1%8C-%D0%BB%D1%83%D1%87%D1%88%D0%B8%D0%B9-vpn-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81/</link><description><![CDATA[<p>
	<strong>Как выбрать лучший VPN сервис?</strong>
</p>

<p>
	В 2025 все чаще люди задумываются о своей безопасности в интернете, сохранности своих данных, приватности. Даже просто получение доступа к привычным онлайн сервисам иногда требует изобретательности. Использование VPN сервиса может снять часть этих забот.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="489" data-ratio="66.55" width="592" alt="VPN.webp.37a25ce5119f70641dfc977eb86deb25.webp" data-src="https://phoenix.lol/uploads/monthly_2025_06/VPN.webp.37a25ce5119f70641dfc977eb86deb25.webp" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	Конечно, не все VPN одинаковы и хочется использовать лучший. На что же следует обратить внимание при выборе? Выбор VPN сервиса в 2025 году требует учета множества факторов, поскольку рынок продолжает развиваться, а требования пользователей к безопасности, скорости и удобству использования увеличиваются.
</p>

<p>
	Основные критерии, которые помогут выбрать лучший сервис:
</p>

<p>
	1. Приватность и защита данных
</p>

<p>
	Прежде всего, VPN должен обеспечивать высокий уровень конфиденциальности. Обратите внимание на политику отказа от логов. Это означает, что провайдер не будет хранить записи о вашей активности в сети. Также важен уровень шифрования.
</p>

<p>
	2. Скорость и стабильность соединения
</p>

<p>
	Одна из возможных проблем при использовании VPN — это замедление интернет соединения. Поэтому важно выбирать сервисы с высокими скоростями и минимальной задержкой. Современные VPN используют серверы с низкой загруженностью, распределенные по всему миру, что помогает обеспечить стабильное соединение даже при высоких нагрузках. Если высокая скорость интернета для вас особенно важна, то стоит задуматься о приобретении платной версии VPN.
</p>

<p>
	3. Географическое разнообразие серверов
</p>

<p>
	Чем больше серверов в разных странах, тем выше возможностей обойти географические ограничения и получить доступ к контенту, заблокированному в вашей стране. Если, например, вы планируете использовать VPN для стриминга видео или доступа к зарубежным сайтам, наличие серверов в нужных регионах будет преимуществом.
</p>

<p>
	4. Совместимость с устройствами и браузерами
</p>

<p>
	Проверьте, поддерживает ли VPN все устройств, которые вы планируете подключать: ПК, смартфоны, планшеты и смарт ТВ. Некоторые сервисы предлагают специальные приложения для различных платформ, что упрощает настройку и использование. Также если вы планируете установить VPN в браузере, то убедитесь, что выбранный провайдер предоставляет расширения для того браузера, который вы предпочитаете.
</p>

<p>
	5. Дополнительные функции
</p>

<p>
	Некоторые VPN предлагают такие дополнительные возможности, как автоматическое отключение при потере соединения (Kill Switch). дополнительные опции повышают общую безопасность использования сети.
</p>

<p>
	6. Стоимость и тарифные планы
</p>

<p>
	Стоимость VPN-сервиса должна быть оправдана качеством предоставляемых услуг. Многие провайдеры предлагают гибкие тарифы с возможностью оплаты за месяц или год. Стоит также обратить внимание на наличие пробных периодов и гарантий возврата денег.
</p>

<p>
	7. Отзывы и репутация
</p>

<p>
	Прежде чем подписываться на выбранный VPN, изучите отзывы реальных пользователей и экспертов. Это поможет вам оценить, насколько надёжен провайдер и какие потенциальные проблемы могут возникнуть в процессе использования.
</p>

<p>
	Подводя итог
</p>

<p>
	Выбор лучшего VPN в 2025 году должен основываться на сочетании безопасности, скорости и удобства, с учетом ваших индивидуальных нужд и предпочтений.
</p>

<p>
	Обратите ваше внимание на <a href="https://vpn.webcluster.org" rel="external nofollow">vpn.webcluster.org</a>, который соответствует всем перечисленным критериям, заботится о вашей безопасности и позволит вам комфортно использовать любые ресурсы в интернете, как раньше.
</p>

<p>
	На сайте действует реферальная программа, если зарегистрируетесь по ссылке то "+ вам в карму"!
</p>

<p>
	<a href="https://webcluster.org/aff.php?aff=1" rel="external nofollow">https://webcluster.org/aff.php?aff=1</a>
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">22</guid><pubDate>Sun, 22 Jun 2025 12:24:05 +0000</pubDate></item><item><title>Getting to Know Ceph Storage in Pictures</title><link>https://phoenix.lol/index.php?/blogs/entry/21-getting-to-know-ceph-storage-in-pictures/</link><description><![CDATA[<p>
	Cloud file storage continues to gain popularity, and the requirements for them continue to grow. Modern systems are no longer able to fully satisfy all these requirements without significant resource expenditures on supporting and scaling these systems. By system, I mean a cluster with one or another level of access to data. For the user, storage reliability and high availability are important, so that files can always be easily and quickly retrieved, and the risk of data loss tends to zero. In turn, for providers and administrators of such storage, ease of support, scalability and low cost of hardware and software components are important.
</p>

<p>
	<strong>Meet Ceph</strong><br />
	<strong>Ceph</strong> is an open-source software-defined distributed file system devoid of bottlenecks and single points of failure, which is an easily scalable to petabyte sizes cluster of nodes performing various functions, providing data storage and replication, as well as load distribution, which guarantees high availability and reliability. The system is free, although the developers can provide paid support. No special equipment is required.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="394" data-ratio="78.57" width="700" alt="1.gif.e55d39accef20d4f64520f609041cc88.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/1.gif.e55d39accef20d4f64520f609041cc88.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	If any disk, node or group of nodes fails, Ceph will not only ensure the safety of the data, but will also restore the lost copies on other nodes until the failed nodes or disks are replaced with working ones. The rebuild occurs without a second of downtime and is transparent to clients.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="395" data-ratio="78.57" width="700" alt="2.gif.b17bc2076683c061687766215fc50c78.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/2.gif.b17bc2076683c061687766215fc50c78.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Node roles and daemons</strong><br />
	Since the system is software-defined and runs on top of standard file systems and network layers, you can take a bunch of different servers, stuff them with different disks of different sizes, connect all this happiness with some network (preferably a fast one) and raise a cluster. You can stick a second network card into these servers and connect them with a second network to speed up interserver data exchange. And experiments with settings and schemes can be easily carried out even in a virtual environment. My experience of experiments shows that the longest part of this process is installing the OS. If we have three servers with disks and a configured network, then raising a working cluster with default settings will take 5-10 minutes (if everything is done correctly).
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="396" data-ratio="71.43" width="700" alt="3.png.1e0ee6e99dde50b8d7b97614c3cd9ffb.png" data-src="https://phoenix.lol/uploads/monthly_2025_01/3.png.1e0ee6e99dde50b8d7b97614c3cd9ffb.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	Ceph daemons run on top of the operating system, performing various roles of the cluster. Thus, one server can act, for example, as a monitor (MON) and as a data storage (OSD). Meanwhile, another server can act as a data storage and as a metadata server (MDS). In large clusters, daemons are launched on separate machines, but in small clusters, where the number of servers is very limited, some servers can perform two or three roles at once. Depends on the server capacity and the roles themselves. Of course, everything will work faster on separate servers, but this is not always possible to implement. A cluster can be assembled even from one machine and only one disk, and it will work. Another conversation is that it will not make sense. It should also be noted that due to software definition, storage can be raised even on top of a RAID or iSCSI device, but in most cases this will not make sense either. The documentation lists 3 types of daemons:
</p>

<ul>
	<li>
		Mon — monitor daemon
	</li>
	<li>
		OSD — storage daemon
	</li>
	<li>
		MDS — metadata server (only required if using CephFS)
	</li>
</ul>

<p>
	The initial cluster can be created from several machines, combining cluster roles on them. Then, as the cluster grows and new servers are added, some roles can be duplicated on other machines or completely moved to separate servers.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="397" data-ratio="78.57" width="700" alt="4.gif.4becee0a894d787b09941bfb6f8ba614.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/4.gif.4becee0a894d787b09941bfb6f8ba614.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Storage structure</strong><br />
	To begin with, briefly and unclearly. A cluster can have one or many data pools of different purposes and with different settings. Pools are divided into placement groups. Placement groups store objects that clients access. This is where the logical level ends and the physical level begins, because each placement group is assigned one main disk and several replica disks (how many exactly depends on the pool replication factor). In other words, at the logical level, an object is stored in a specific placement group, and at the physical level, on the disks that are assigned to it. In this case, the disks can be physically located on different nodes or even in different data centers.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="398" data-ratio="73.43" width="700" alt="5.png.a4b2cdb666838f60c582b24e84ad3a4b.png" data-src="https://phoenix.lol/uploads/monthly_2025_01/5.png.a4b2cdb666838f60c582b24e84ad3a4b.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<em>Further in detail &amp; clear.</em><br />
	<strong>Replication factor (RF)</strong><br />
	The replication factor is the level of data redundancy. The number of copies of data that will be stored on different disks. The size variable is responsible for this parameter. The replication factor can be different for each pool, and it can be changed on the fly. In general, in Ceph, almost all parameters can be changed on the fly, instantly receiving a cluster response. At first, we can have size=2, and in this case, the pool will store two copies of one piece of data on different disks. This pool parameter can be changed to size=3, and at the same time, the cluster will begin to redistribute data, spreading another copy of the existing data across disks without stopping the work of clients.
</p>

<p>
	<strong>Pool</strong><br />
	A pool is a logical abstract container for organizing the storage of user data. Any data is stored in the pool as objects. Several pools can be spread across the same disks (or different ones, depending on how to configure) using different sets of placement groups. Each pool has a number of configurable parameters: replication factor, number of placement groups, minimum number of live object replicas required for operation, etc. Each pool can have its own replication policy (by city, data center, rack, or even disk). For example, a hosting pool can have a replication factor of size=3, and the failure zone will be data centers. Then Ceph will guarantee that each piece of data has one copy in three data centers. Meanwhile, a pool for virtual machines can have a replication factor of size=2, and the failure level will be a server rack. And in this case, the cluster will store only two copies. At the same time, if we have two racks with virtual image storage in one data center, and two racks in another, the system will not pay attention to the data centers, and both copies of the data can fly to one data center, but guaranteed to different racks, as we wanted. Placement group (PG)<br />
	Placement groups are a link between the physical storage level (disks) and the logical organization of data (pools).
</p>

<p>
	Each object at the logical level is stored in a specific placement group. At the physical level, it is stored in the required number of copies on different physical disks that are included in this placement group (in fact, not disks, but OSDs, but usually one OSD is one disk, and for simplicity I will call it a disk, although I remind you that there can be a RAID array or an iSCSI device behind it). With a replication factor of size=3, each placement group includes three disks. But at the same time, each disk is in many placement groups, and for some groups it will be primary, for others - a replica. If an OSD is, for example, part of three placement groups, then when such an OSD fails, the placement groups will exclude it from operation, and each placement group will select a working OSD in its place and spread the data across it. This mechanism achieves a fairly uniform distribution of data and load. This is a very simple and flexible solution at the same time.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="399" data-ratio="64.29" width="700" alt="6.gif.f7e8deece6972214eed64926e0e3bad3.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/6.gif.f7e8deece6972214eed64926e0e3bad3.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Monitors</strong><br />
	A monitor is a daemon that acts as a coordinator, from which a cluster starts. As soon as we have at least one working monitor, we have a Ceph cluster. The monitor stores information about the health and state of the cluster, exchanging various maps with other monitors. Clients access monitors to find out which OSDs to write/read data to. When deploying a new storage, the first thing to do is create a monitor (or several). A cluster can live on one monitor, but it is recommended to make 3 or 5 monitors, in order to avoid the entire system crashing due to the failure of a single monitor. The main thing is that their number is odd, in order to avoid split-brain situations. Monitors work in a quorum, so if more than half of the monitors fail, the cluster will lock to prevent data inconsistency.
</p>

<p>
	<strong>OSD (Object Storage Device)</strong><br />
	OSD is a storage unit that stores the data itself and processes client requests, exchanging data with other OSDs. Usually this is a disk. And usually a separate OSD daemon is responsible for each OSD, which can be launched on any machine where this disk is installed. This is the second thing that needs to be added to the cluster when deploying. One monitor and one OSD is the minimum set to raise the cluster and start using it. If the server has 12 disks for storage, then the same number of OSD daemons will be launched on it. Clients work directly with the OSDs themselves, bypassing bottlenecks and thereby achieving load distribution. The client always writes an object to the primary OSD for some placement group, and then this OSD synchronizes the data with the rest (secondary) OSDs from the same placement group. Confirmation of a successful write can be sent to the client immediately after writing to the primary OSD, or after reaching the minimum number of records (the min_size pool parameter). For example, if the replication factor size=3 and min_size=2, then a confirmation of successful write will be sent to the client when the object is written to at least two OSDs out of three (including the primary).
</p>

<p>
	With different configuration options for these parameters, we will also observe different behavior.
</p>

<p>
	If size=3 and min_size=2: everything will be fine while 2 out of 3 OSDs of the placement group are alive. When only 1 OSD is alive, the cluster will freeze the operations of this placement group until at least one more OSD comes to life.
</p>

<p>
	If size=min_size, then the placement group will be blocked when any OSD in it crashes. And due to the high level of data smearing, most crashes of at least one OSD will end with the entire or almost entire cluster freezing. Therefore, the size parameter should always be at least one point larger than the min_size parameter.
</p>

<p>
	If size=1, the cluster will work, but the death of any OSD will mean irreversible data loss. Ceph allows you to set this parameter to one, but even if the administrator does it for a specific purpose for a short time, he takes the risk.
</p>

<p>
	The OSD disk consists of two parts: the journal and the data itself. Accordingly, the data is first written to the journal, and then to the data section. On the one hand, this provides additional reliability and some optimization, and on the other hand, it is an additional operation that affects performance. The issue of journal performance will be discussed below.
</p>

<p>
	<strong>CRUSH Algorithm</strong><br />
	The decentralization and distribution mechanism is based on the so-called CRUSH algorithm (Controlled Replicated Under Scalable Hashing), which plays an important role in the system architecture. This algorithm allows you to uniquely determine the location of an object based on the hash of the object name and a specific map, which is formed based on the physical and logical structures of the cluster (data centers, halls, rows, racks, nodes, disks). The map does not include information about the location of the data. Each client determines the path to the data himself, using the CRUSH algorithm and the current map, which he asks the monitor in advance. When a disk is added or a server crashes, the map is updated.
</p>

<p>
	Due to determinism, two different clients will find the same unambiguous path to one object independently, freeing the system from the need to keep all these paths on some servers, synchronizing them with each other, giving a huge excess load on the storage as a whole.
</p>

<p>
	Example:
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="400" data-ratio="71.43" width="700" alt="7.gif.67aa88d6b921dc74208f755e7cf93513.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/7.gif.67aa88d6b921dc74208f755e7cf93513.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	The client wants to write a certain object object1 to the pool Pool1. To do this, he looks at the placement group map, which the monitor kindly provided him earlier, and sees that Pool1 is divided into 10 placement groups. Then, using the CRUSH algorithm, which takes the object name and the total number of placement groups in Pool1 as input, the placement group ID is calculated. Following the map, the client understands that three OSDs are assigned to this placement group (let's say their numbers are: 17, 9 and 22), the first of which is primary, which means the client will write to it. By the way, there are three of them, because the replication factor size=3 is set in this pool. After successfully writing the object to OSD_17, the client's work is finished (this is if the pool parameter min_size=1), and OSD_17 replicates this object to OSD_9 and OSD_22 assigned to this placement group. It is important to understand that this is a simplified explanation of how the algorithm works.
</p>

<p>
	By default, our CRUSH map is flat, all nodes are in the same space. However, this plane can be easily turned into a tree by distributing servers by racks, racks by rows, rows by halls, halls by data centers, and data centers by different cities and planets, specifying which level is considered a failure zone. Operating with such a new map, Ceph will distribute data more intelligently, taking into account the individual characteristics of the organization, preventing the tragic consequences of a fire in a data center or a meteorite falling on an entire city. Moreover, thanks to this flexible mechanism, you can create additional layers, both at the upper levels (data centers and cities) and at the lower ones (for example, additional division into disk groups within a single server).
</p>

<p>
	<strong>Caching</strong><br />
	Ceph provides several ways to increase cluster performance using caching methods.
</p>

<p>
	<strong>Primary-Affinity</strong><br />
	Each OSD has several weights, and one of them is responsible for which OSD in the placement group will be primary. And, as we found out earlier, the client writes data to the primary OSD. So, you can add a bunch of SSD disks to the cluster, making them always primary, reducing the weight of the primary-affinity HDD disks to zero. And then the recording will always be performed first on a fast disk, and then slowly replicated to the slow ones. This method is the most incorrect, but the easiest to implement. The main drawback is that one copy of the data will always be on the SSD and a lot of such disks will be required to fully cover the replication. Although someone has used this method in practice, I rather mentioned it to talk about the possibility of managing the write priority.
</p>

<p>
	<strong>Moving logs to SSD</strong><br />
	In general, the lion's share of performance depends on the OSD logs. When writing, the daemon first writes data to the log, and then to the storage itself. This is always true, except for cases of using BTRFS as a file system on the OSD, which can do this in parallel thanks to the copy-on-write technique, but I still do not understand how ready it is for industrial use. Each OSD has its own journal, and by default it is located on the same disk as the data itself. However, journals from four or five disks can be moved to one SSD, significantly accelerating write operations. The method is not very flexible and convenient, but quite simple. The disadvantage of the method is that if the SSD with the journal crashes, we will lose several OSDs at once, which is not very pleasant and introduces additional difficulties into all further support, which scales with cluster growth.
</p>

<p>
	<strong>Cache-tiering</strong><br />
	The orthodoxy of this method is in its flexibility and scalability. The scheme is such that we have a pool with cold data and a pool with hot data. When an object is frequently accessed, it heats up and ends up in a hot pool, which consists of fast SSDs. Then, if the object cools down, it ends up in a cold pool with slow HDDs. This scheme makes it easy to change SSDs in a hot pool, which in turn can be of any size, because the heating and cooling parameters are adjustable.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="401" data-ratio="42.86" width="700" alt="8.gif.670366cadeab7481eb26fbb13aaf60f5.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/8.gif.670366cadeab7481eb26fbb13aaf60f5.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	From the client's perspective
</p>

<p>
	Ceph provides the client with different options for accessing data: block device, file system or object storage.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="402" data-ratio="69.67" width="600" alt="9.jpg.a882b9badc4f885fea0b9baa3c06948f.jpg" data-src="https://phoenix.lol/uploads/monthly_2025_01/9.jpg.a882b9badc4f885fea0b9baa3c06948f.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Block device (RBD, Rados Block Device)</strong><br />
	Ceph allows you to create an RBD block device in the data pool, and then mount it on operating systems that support it (at the time of writing, there were only various Linux distributions, but FreeBSD and VMWare also work in this direction). If the client does not support RBD (for example, Windows), then you can use an intermediate iSCSI target with RBD support (for example, tgt-rbd). In addition, such a block device supports snapshots.
</p>

<p>
	<strong>CephFS file system</strong><br />
	A client can mount a CephFS file system if it has Linux with kernel version 2.6.34 or newer. If the kernel version is older, it can be mounted via FUSE (Filesystem in User Space). In order for clients to be able to connect Ceph as a file system, it is necessary to raise at least one metadata server (MDS) in the cluster
</p>

<p>
	<strong>Object gateway</strong><br />
	Using the RGW (RADOS Gateway), you can give clients the ability to use storage via a RESTful Amazon S3 or OpenStack Swift compatible API.
</p>

<p>
	And others...<br />
	All these data access layers work on top of the RADOS layer. The list can be supplemented by developing your own data access layer using the librados API (through which the above access layers work). At the moment, there are bindings for C, Python, Ruby, Java, and PHP
</p>

<p>
	<strong>RADOS</strong> (Reliable Autonomic Distributed Object Store), in a nutshell, is a layer for interaction between clients and the cluster.
</p>

<p>
	Wikipedia says that Ceph itself is written in C++ and Python, and Canonical, CERN, Cisco, Fujitsu, Intel, Red Hat, SanDisk, and SUSE are participating in the development.
</p>

<p>
	<strong>Impressions</strong><br />
	Why did I write all this and draw pictures? Because despite all these advantages, Ceph is either not very popular, or people eat it up quietly, judging by the amount of information about it on the Internet.
</p>

<p>
	We have found out that Ceph is flexible, simple and convenient. A cluster can be set up on any hardware in a regular network, spending a minimum of time and effort, while Ceph itself will take care of the safety of the data, taking the necessary measures in case of hardware failures. Many points of view agree that Ceph is flexible, simple and scalable. However, reviews of performance are quite varied. Perhaps someone could not cope with the logs, someone was let down by the network and delays in I/O operations. That is, making a cluster work is easy, but making it work quickly is perhaps more difficult. Therefore, I appeal to IT specialists who have experience using Ceph in production. Share your negative impressions in the comments.
</p>

<p>
	 
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">21</guid><pubDate>Wed, 22 Jan 2025 21:00:39 +0000</pubDate></item><item><title>&#x417;&#x43D;&#x430;&#x43A;&#x43E;&#x43C;&#x441;&#x442;&#x432;&#x43E; &#x441; &#x445;&#x440;&#x430;&#x43D;&#x438;&#x43B;&#x438;&#x449;&#x435;&#x43C; Ceph &#x432; &#x43A;&#x430;&#x440;&#x442;&#x438;&#x43D;&#x43A;&#x430;&#x445;</title><link>https://phoenix.lol/index.php?/blogs/entry/20-%D0%B7%D0%BD%D0%B0%D0%BA%D0%BE%D0%BC%D1%81%D1%82%D0%B2%D0%BE-%D1%81-%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B5%D0%BC-ceph-%D0%B2-%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%D1%85/</link><description><![CDATA[<p>
	Облачные файловые хранилища продолжают набирать популярность, и требования к ним продолжают расти. Современные системы уже не в состоянии полностью удовлетворить все эти требования без значительных затрат ресурсов на поддержку и масштабирование этих систем. Под системой я подразумеваю кластер с тем или иным уровнем доступа к данным. Для пользователя важна надежность хранения и высокая доступность, чтобы файлы можно было всегда легко и быстро получить, а риск потери данных стремился к нулю. В свою очередь для поставщиков и администраторов таких хранилищ важна простота поддержки, масштабируемость и низкая стоимость аппаратных и программных компонентов.
</p>

<p>
	<strong>Знакомьтесь: Ceph</strong><br />
	Ceph — это программно определяемая распределенная файловая система с открытым исходным кодом, лишенная узких мест и единых точек отказа, которая представляет из себя легко масштабируемый до петабайтных размеров кластер узлов, выполняющих различные функции, обеспечивая хранение и репликацию данных, а также распределение нагрузки, что гарантирует высокую доступность и надежность. Система бесплатная, хотя разработчики могут предоставить платную поддержку. Никакого специального оборудования не требуется.
</p>

<p>
	<img alt="1.gif.e9466f680b4aa134963f87627c12fcdd.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="375" data-ratio="78.57" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/1.gif.e9466f680b4aa134963f87627c12fcdd.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	При выходе любого диска, узла или группы узлов из строя Ceph не только обеспечит сохранность данных, но и сам восстановит утраченные копии на других узлах до тех пор, пока вышедшие из строя узлы или диски не заменят на рабочие. При этом ребилд происходит без секунды простоя и прозрачно для клиентов.
</p>

<p>
	<img alt="2.gif.841e6bf8c2225dbb969804edc7372eb2.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="376" data-ratio="78.57" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/2.gif.841e6bf8c2225dbb969804edc7372eb2.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Роли узлов и демоны</strong><br />
	Поскольку система программно определяемая и работает поверх стандартных файловых систем и сетевых уровней, можно взять пачку разных серверов, набить их разными дисками разного размера, соединить всё это счастье какой-нибудь сетью (лучше быстрой) и поднять кластер. Можно воткнуть в эти серверы по второй сетевой карте, и соединить их второй сетью для ускорения межсерверного обмена данными. А эксперименты с настройками и схемами можно легко проводить даже в виртуальной среде. Мой опыт экспериментов показывает, что самое долгое в этом процессе — это установка ОС. Если у нас есть три сервера с дисками и настроенной сетью, то поднятие работоспособного кластера с дефолтными настройками займет 5-10 минут (если все делать правильно).
</p>

<p>
	<img alt="3.png.87412dc51b0f97d44d546ac048651dfe.png" class="ipsImage ipsImage_thumbnailed" data-fileid="378" data-ratio="71.43" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/3.png.87412dc51b0f97d44d546ac048651dfe.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	Поверх операционной системы работают демоны Ceph, выполняющие различные роли кластера. Таким образом один сервер может выступать, например, и в роли монитора (MON), и в роли хранилища данных (OSD). А другой сервер тем временем может выступать в роли хранилища данных и в роли сервера метаданных (MDS). В больших кластерах демоны запускаются на отдельных машинах, но в малых кластерах, где количество серверов сильно ограничено, некоторые сервера могут выполнять сразу две или три роли. Зависит от мощности сервера и самих ролей. Разумеется, все будет работать шустрее на отдельных серверах, но не всегда это возможно реализовать. Кластер можно собрать даже из одной машины и всего одного диска, и он будет работать. Другой разговор, что это не будет иметь смысла. Следует отметить и то, что благодаря программной определяемости, хранилище можно поднять даже поверх RAID или iSCSI-устройства, однако в большинстве случаев это тоже не будет иметь смысла.<br />
	<br />
	В документации перечислено 3 вида демонов:<br />
	 
</p>

<ul>
	<li>
		Mon — демон монитора
	</li>
	<li>
		OSD — демон хранилища
	</li>
	<li>
		MDS — сервер метаданных (необходим только в случае использования CephFS)
	</li>
</ul>

<p>
	<br />
	Первоначальный кластер можно создать из нескольких машин, совмещая на них роли кластера. Затем, с ростом кластера и добавлением новых серверов, какие-то роли можно дублировать на других машинах или полностью выносить на отдельные серверы.
</p>

<p>
	<img alt="4.gif.aac2dd70fa947ad1e3ab1cda99067341.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="379" data-ratio="78.57" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/4.gif.aac2dd70fa947ad1e3ab1cda99067341.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Структура хранения</strong><br />
	Для начала коротко и непонятно. Кластер может иметь один или много пулов данных разного назначения и с разными настройками. Пулы делятся на плейсмент-группы. В плейсмент-группах хранятся объекты, к которым обращаются клиенты. На этом логический уровень заканчивается, и начинается физический, потому как за каждой плейсмент-группой закреплен один главный диск и несколько дисков-реплик (сколько именно зависит от фактора репликации пула). Другими словами, на логическом уровне объект хранится в конкретной плейсмент-группе, а на физическом — на дисках, которые за ней закреплены. При этом диски физически могут находиться на разных узлах или даже в разных датацентрах.
</p>

<p>
	<img alt="5.png.0c0087276c32eac80ba8b1fd53d39983.png" class="ipsImage ipsImage_thumbnailed" data-fileid="380" data-ratio="73.43" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/5.png.0c0087276c32eac80ba8b1fd53d39983.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	 
</p>

<p>
	<em>Далее подробно &amp; понятно.</em><br />
	<strong>Фактор репликации (RF)</strong><br />
	Фактор репликации — это уровень избыточности данных. Количество копий данных, которое будет храниться на разных дисках. За этот параметр отвечает переменная size. Фактор репликации может быть разным для каждого пула, и его можно менять на лету. Вообще, в Ceph практически все параметры можно менять на лету, мгновенно получая реакцию кластера. Сначала у нас может быть size=2, и в этом случае, пул будет хранить по две копии одного куска данных на разных дисках. Этот параметр пула можно поменять на size=3, и в этот же момент кластер начнет перераспределять данные, раскладывая еще одну копию уже имеющихся данных по дискам, не останавливая работу клиентов.<br />
	 
</p>

<p>
	<strong>Пул</strong><br />
	Пул — это логический абстрактный контейнер для организации хранения данных пользователя. Любые данные хранятся в пуле в виде объектов. Несколько пулов могут быть размазаны по одним и тем же дискам (а может и по разным, как настроить) с помощью разных наборов плейсмент-групп. Каждый пул имеет ряд настраиваемых параметров: фактор репликации, количество плейсмент-групп, минимальное количество живых реплик объекта, необходимое для работы и т. д. Каждому пулу можно настроить свою политику репликации (по городам, датацентрам, стойкам или даже дискам). Например, пул под хостинг может иметь фактор репликации size=3, а зоной отказа будут датацентры. И тогда Ceph будет гарантировать, что каждый кусочек данных имеет по одной копии в трех датацентрах. Тем временем, пул для виртуальных машин может иметь фактор репликации size=2, а уровнем отказа уже будет серверная стойка. И в этом случае, кластер будет хранить только две копии. При этом, если у нас две стойки с хранилищем виртуальных образов в одном датацентре, и две стойки в другом, система не будет обращать внимание на датацентры, и обе копии данных могут улететь в один датацентр, однако гарантированно в разные стойки, как мы и хотели.<br />
	 
</p>

<p>
	<strong>Плейсмент-группа (PG)</strong><br />
	Плейсмент-группы — это такое связующее звено между физическим уровнем хранения (диски) и логической организацией данных (пулы).<br />
	<br />
	Каждый объект на логическом уровне хранится в конкретной плейсмент-группе. На физическом же уровне, он лежит в нужном количестве копий на разных физических дисках, которые в эту плейсмент-группу включены (на самом деле не диски, а OSD, но обычно один OSD это и есть один диск, и для простоты я буду называть это диском, хотя напомню, за ним может быть и RAID-массив или iSCSI-устройство). При факторе репликации size=3, каждая плейсмент группа включает в себя три диска. Но при этом каждый диск находится во множестве плейсмент-групп, и для каких то групп он будет первичным, для других — репликой. Если OSD входит, например, в состав трех плейсмент-групп, то при падении такого OSD, плейсмент-группы исключат его из работы, и на его место каждая плейсмент-группа выберет рабочий OSD и размажет по нему данные. С помощью данного механизма и достигается достаточно равномерное распределение данных и нагрузки. Это весьма простое и одновременно гибкое решение.
</p>

<p>
	<img alt="6.gif.2e655c8d600b5fe6a5dccb3091c648ba.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="381" data-ratio="64.29" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/6.gif.2e655c8d600b5fe6a5dccb3091c648ba.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	 
</p>

<p>
	<strong>Мониторы</strong><br />
	Монитор — это демон, выполняющий роль координатора, с которого начинается кластер. Как только у нас появляется хотя бы один рабочий монитор, у нас появляется Ceph-кластер. Монитор хранит информацию о здоровье и состоянии кластера, обмениваясь различными картами с другими мониторами. Клиенты обращаются к мониторам, чтобы узнать, на какие OSD писать/читать данные. При разворачивании нового хранилища, первым делом создается монитор (или несколько). Кластер может прожить на одном мониторе, но рекомендуется делать 3 или 5 мониторов, во избежание падения всей системы по причине падения единственного монитора. Главное, чтобы количество оных было нечетным, дабы избежать ситуаций раздвоения сознания (split-brain). Мониторы работают в кворуме, поэтому если упадет больше половины мониторов, кластер заблокируется для предотвращения рассогласованности данных.<br />
	 
</p>

<p>
	<strong>OSD (Object Storage Device)</strong><br />
	OSD — это юнит хранилища, который хранит сами данные и обрабатывает запросы клиентов, обмениваясь данными с другими OSD. Обычно это диск. И обычно за каждый OSD отвечает отдельный OSD-демон, который может запускаться на любой машине, на которой установлен этот диск. Это второе, что нужно добавлять в кластер, при разворачивании. Один монитор и один OSD — минимальный набор для того, чтобы поднять кластер и начать им пользоваться. Если на сервере крутится 12 дисков под хранилище, то на нем будет запущено столько же OSD-демонов. Клиенты работают непосредственно с самими OSD, минуя узкие места, и достигая, тем самым, распределения нагрузки. Клиент всегда записывает объект на первичный OSD для какой-то плейсмент группы, а уже дальше данный OSD синхронизирует данные с остальными (вторичными) OSD из этой же плейсмент-группы. Подтверждение успешной записи может отправляться клиенту сразу же после записи на первичный OSD, а может после достижения минимального количества записей (параметр пула min_size). Например если фактор репликации size=3, а min_size=2, то подтверждение об успешной записи отправится клиенту, когда объект запишется хотя бы на два OSD из трех (включая первичный).<br />
	<br />
	При разных вариантах настройки этих параметров, мы будем наблюдать и разное поведение.<br />
	<br />
	Если size=3 и min_size=2: все будет хорошо, пока 2 из 3 OSD плейсмент-группы живы. Когда останется всего лишь 1 живой OSD, кластер заморозит операции данной плейсмент-группы, пока не оживет хотя бы еще один OSD.<br />
	<br />
	Если size=min_size, то плейсмент-группа будет блокироваться при падении любого OSD, входящего в ее состав. А из-за высокого уровня размазанности данных, большинство падений хотя бы одного OSD будет заканчиваться заморозкой всего или почти всего кластера. Поэтому параметр size всегда должен быть хотя бы на один пункт больше параметра min_size.<br />
	<br />
	Если size=1, кластер будет работать, но смерть любой OSD будет означать безвозвратную потерю данных. Ceph дозволяет выставить этот параметр в единицу, но даже если администратор делает это с определенной целью на короткое время, он риск берет на себя.<br />
	<br />
	Диск OSD состоит из двух частей: журнал и сами данные. Соответственно, данные сначала пишутся в журнал, затем уже в раздел данных. С одной стороны это дает дополнительную надежность и некоторую оптимизацию, а с другой стороны — дополнительную операцию, которая сказывается на производительности. Вопрос производительности журналов рассмотрим ниже.<br />
	 
</p>

<p>
	<strong>Алгоритм CRUSH</strong><br />
	В основе механизма децентрализации и распределения лежит так называемый CRUSH-алгоритм (Controlled Replicated Under Scalable Hashing), играющий важную роль в архитектуре системы. Этот алгоритм позволяет однозначно определить местоположение объекта на основе хеша имени объекта и определенной карты, которая формируется исходя из физической и логической структур кластера (датацентры, залы, ряды, стойки, узлы, диски). Карта не включает в себя информацию о местонахождении данных. Путь к данным каждый клиент определяет сам, с помощью CRUSH-алгоритма и актуальной карты, которую он предварительно спрашивает у монитора. При добавлении диска или падении сервера, карта обновляется.<br />
	<br />
	Благодаря детерминированности, два разных клиента найдут один и тот же однозначный путь до одного объекта самостоятельно, избавляя систему от необходимости держать все эти пути на каких-то серверах, синхронизируя их между собой, давая огромную избыточную нагрузку на хранилище в целом.<br />
	<br />
	Пример:
</p>

<p>
	<img alt="7.gif.90fb09f5085f502396372579d33f7803.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="382" data-ratio="71.43" style="height:auto;" width="700" data-src="https://phoenix.lol/uploads/monthly_2025_01/7.gif.90fb09f5085f502396372579d33f7803.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	Клиент хочет записать некий объект object1 в пул Pool1. Для этого он смотрит в карту плейсмент-групп, которую ему ранее любезно предоставил монитор, и видит, что Pool1 разделен на 10 плейсмент-групп. Далее с помощью CRUSH-алгоритма, который на вход принимает имя объекта и общее количество плейсмент-групп в пуле Pool1, вычисляется ID плейсмент-группы. Следуя карте, клиент понимает, что за этой плейсмент-группой закреплено три OSD (допустим, их номера: 17, 9 и 22), первый из которых является первичным, а значит клиент будет производить запись именно на него. Кстати, их три, потому что в этом пуле установлен фактор репликации size=3. После успешной записи объекта на OSD_17, работа клиента закончена (это если параметр пула min_size=1), а OSD_17 реплицирует этот объект на OSD_9 и OSD_22, закрепленные за этой плейсмент-группой. Важно понимать, что это упрощенное объяснение работы алгоритма.<br />
	<br />
	По умолчанию наша CRUSH-карта плоская, все ноды находятся в одном пространстве. Однако, можно эту плоскость легко превратить в дерево, распределив серверы по стойкам, стойки по рядам, ряды по залам, залы по датацентрам, а датацентры по разным городам и планетам, указав какой уровень считать зоной отказа. Оперируя такой новой картой, Ceph будет грамотнее распределять данные, учитывая индивидуальные особенности организации, предотвращая печальные последствия пожара в датацентре или падения метеорита на целый город. Более того, благодаря этому гибкому механизму, можно создавать дополнительные слои, как на верхних уровнях (датацентры и города), так и на нижних (например, дополнительное разделение на группы дисков в рамках одного сервера).<br />
	 
</p>

<p>
	<strong>Кэширование</strong><br />
	<strong>Ceph</strong> предусматривает несколько способов увеличения производительности кластера методами кэширования.<br />
	<br />
	<strong>Primary-Affinity</strong><br />
	У каждого OSD есть несколько весов, и один из них отвечает за то, какой OSD в плейсмент-группе будет первичным. А, как мы выяснили ранее, клиент пишет данные именно на первичный OSD. Так вот, можно добавить в кластер пачку SSD дисков, сделав их всегда первичными, снизив вес primary-affinity HDD дисков до нуля. И тогда запись будет осуществляться всегда сначала на быстрый диск, а затем уже не спеша реплицироваться на медленные. Этот метод самый неправильный, однако самый простой в реализации. Главный недостаток в том, что одна копия данных всегда будет лежать на SSD и потребуется очень много таких дисков, чтобы полностью покрыть репликацию. Хотя этот способ кто-то и применял на практике, но его я скорее упомянул для того, чтобы рассказать о возможности управления приоритетом записи.<br />
	<br />
	<strong>Вынос журналов на SSD</strong><br />
	Вообще, львиная доля производительности зависит от журналов OSD. Осуществляя запись, демон сначала пишет данные в журнал, а затем в само хранилище. Это верно всегда, кроме случаев использования BTRFS в качестве файловой системы на OSD, которая может делать это параллельно благодаря технике copy-on-write, но я так и не понял, насколько она готова к промышленному применению. На каждый OSD идет собственный журнал, и по умолчанию он находится на том же диске, что и сами данные. Однако, журналы с четырёх или пяти дисков можно вынести на один SSD, неплохо ускорив операции записи. Метод не очень гибкий и удобный, но достаточно простой. Недостаток метода в том, что при вылете SSD с журналом, мы потеряем сразу несколько OSD, что не очень приятно и вносит дополнительные трудности во всю дальнейшую поддержку, которая скалируется с ростом кластера.<br />
	<br />
	<strong>Кэш-тиринг</strong><br />
	Ортодоксальность данного метода в его гибкости и масштабируемости. Схема такова, что у нас есть пул с холодными данными и пул с горячими. При частом обращении к объекту, тот как бы нагревается и попадает в горячий пул, который состоит из быстрых SSD. Затем, если объект остывает, он попадает в холодный пул с медленными HDD. Данная схема позволяет легко менять SSD в горячем пуле, который в свою очередь может быть любого размера, ибо параметры нагрева и охлаждения регулируются.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="384" data-ratio="42.86" width="700" alt="8.gif.e30f58e177d994aac5f304891379ac20.gif" data-src="https://phoenix.lol/uploads/monthly_2025_01/8.gif.e30f58e177d994aac5f304891379ac20.gif" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	С точки зрения клиента
</p>

<p>
	<br />
	Ceph предоставляет для клиента различные варианты доступа к данным: блочное устройство, файловая система или объектное хранилище.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="393" data-ratio="69.67" width="600" alt="9.jpg.2a661aff4507bcdde47da4d60209bf1c.jpg" data-src="https://phoenix.lol/uploads/monthly_2025_01/9.jpg.2a661aff4507bcdde47da4d60209bf1c.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>Блочное устройство (RBD, Rados Block Device)</strong><br />
	Ceph позволяет в пуле данных создать блочное устройство RBD, и в дальнейшем смонтировать его на операционных системах, которые это поддерживают (на момент написания статьи были только различные дистрибутивы linux, однако FreeBSD и VMWare тоже работают в эту сторону). Если клиент не поддерживает RBD (например Windows), то можно использовать промежуточный iSCSI-target с поддержкой RBD (например, tgt-rbd). Кроме того, такое блочное устройство поддерживает снапшоты.<br />
	<br />
	<strong>Файловая система CephFS</strong><br />
	Клиент может смонтировать файловую систему CephFS, если у него linux с версией ядра 2.6.34 или новее. Если версия ядра старше, то можно смонтировать ее через FUSE (Filesystem in User Space). Для того, чтобы клиенты могли подключать Ceph как файловую систему, необходимо в кластере поднять хотя бы один сервер метаданных (MDS)<br />
	<br />
	<strong>Шлюз объектов</strong><br />
	С помощью шлюза RGW (RADOS Gateway) можно клиентам дать возможность пользоваться хранилищем через RESTful Amazon S3 или OpenStack Swift совместимое API.<br />
	<br />
	И другие...<br />
	Все эти уровни доступа к данным работают поверх уровня RADOS. Список можно дополнить, разработав свой слой доступа к данным с помощью librados API (через который и работают перечисленные выше слои доступа). На данный момент есть биндинги C, Python, Ruby, Java и PHP<br />
	<br />
	<strong>RADOS</strong> (Reliable Autonomic Distributed Object Store), если в двух словах, то это слой взаимодействия клиентов и кластера.<br />
	<br />
	Википедия гласит, что сам Ceph написан на C++ и Python, а в разработке принимают участие компании Canonical, CERN, Cisco, Fujitsu, Intel, Red Hat, SanDisk, and SUSE.<br />
	 
</p>

<p>
	<strong>Впечатления</strong><br />
	Зачем я все это написал и нарисовал картинков? Затем что не смотря на все эти достоинства, Ceph либо не очень популярен, либо люди кушают его втихомолку, судя по количеству информации о нем в интернете.<br />
	<br />
	То, что Ceph гибкий, простой и удобный, мы выяснили. Кластер можно поднять на любом железе в обычной сети, потратив минимум времени и сил, при этом Ceph сам будет заботиться о сохранности данных, предпринимая необходимые меры в случае сбоев железа. В том, что Ceph гибкий, простой и масштабируемый сходится множество точек зрения. Однако отзывы о производительности встречаются весьма разнообразные. Возможно кто-то не справился с журналами, кого-то подвела сеть и задержки в операциях ввода/вывода. То есть, заставить кластер работать — легко, но заставить его работать быстро — возможно, сложнее. Посему, я взываю к ИТ-специалистам, которые имеют опыт использования Ceph в продакшене. Поделитесь в комментариях о своих отрицательных впечатлениях.
</p>
]]></description><guid isPermaLink="false">20</guid><pubDate>Wed, 22 Jan 2025 20:34:28 +0000</pubDate></item><item><title>How to Set Up an NFS Mount on Debian or Ubuntu</title><link>https://phoenix.lol/index.php?/blogs/entry/19-how-to-set-up-an-nfs-mount-on-debian-or-ubuntu/</link><description><![CDATA[<p>
	<strong>How to Set Up an NFS Mount on Debian or Ubuntu</strong>
</p>

<p>
	<strong>Introduction</strong>
</p>

<p>
	NFS, or Network File System, is a distributed file system protocol that allows you to mount remote directories on your server. This allows you to manage storage space in a different location and write to that space from multiple clients. NFS provides a relatively standard and performant way to access remote systems over a network and works well in situations where the shared resources must be accessed regularly.
</p>

<p>
	In this guide, you’ll go over how to install the software needed for NFS functionality on Debian, configure two NFS mounts on a server and client, and mount and unmount the remote shares.
</p>

<p>
	<strong>Step 1 — Downloading and Installing the Components</strong>
</p>

<p>
	You’ll begin by installing the necessary components on each server.
</p>

<p>
	On the Host
</p>

<p>
	On the host server, install the <em>nfs-kernel-server</em> package, which will allow you to share your directories. Since this is the first operation that you’re performing with <em>apt</em> in this session, refresh your local package index before the installation:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo apt update
sudo apt install nfs-kernel-server</span></pre>

<p>
	Once these packages are installed, switch to the <em>client</em> server.
</p>

<p>
	<strong>On the Client</strong>
</p>

<p>
	On the client server, you need to install a package called nfs-common, which provides NFS functionality without including any server components. Again, refresh the local package index prior to installation to ensure that you have up-to-date information:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo apt update
sudo apt install nfs-common</span></pre>

<p>
	Now that both servers have the necessary packages, you can start configuring them.
</p>

<p>
	<strong>Step 2 — Creating the Share Directories on the Host</strong>
</p>

<p>
	You’re going to share two separate directories with different configuration settings, in order to illustrate two key ways that NFS mounts can be configured with respect to superuser access.
</p>

<p>
	Superusers can do anything anywhere on their system. However, NFS-mounted directories are not part of the system on which they are mounted, so by default, the NFS server refuses to perform operations that require superuser privileges. This default restriction means that superusers on the <em>client</em> cannot write files as <em>root</em>, reassign ownership, or perform any other superuser tasks on the NFS mount.
</p>

<p>
	Sometimes, however, there are trusted users on the client system who need to perform these actions on the mounted file system but who have no need for superuser access on the host. You can configure the NFS server to allow this, although it introduces an element of risk, as such a user could gain root access to the entire host system.
</p>

<p>
	<strong>Example 1: Exporting a General Purpose Mount</strong>
</p>

<p>
	In the first example, you’ll create a general-purpose NFS mount that uses default NFS behavior to make it difficult for a user with root privileges on the client machine to interact with the host using those client superuser privileges. You might use something like this to store files which were uploaded using a content management system or to create space for users to easily share project files.
</p>

<p>
	First, make the share directory on the host server:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo mkdir /var/nfs/general -p</span></pre>

<p>
	The <em>-p</em> option for <em>mkdir</em> creates the directory and, if required, all parent directories.
</p>

<p>
	Since you’re creating it with <em>sudo</em>, the directory is owned by the <em>host’s root</em> user:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">ls -dl /var/nfs/general</span></pre>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">Output

drwxr-xr-x 2 root root 4096 Apr 17 23:51 /var/nfs/general</span></pre>

<p>
	NFS will translate any root operations on the client to the nobody:nogroup credentials as a security measure. Therefore, you need to change the directory ownership to match those credentials.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo chown nobody:nogroup /var/nfs/general
Output
drwxr-xr-x 2 nobody nogroup 4096 Apr 17 23:51 /var/nfs/general</span></pre>

<p>
	You’re now ready to export this directory.
</p>

<p>
	<strong>Example 2: Exporting the Home Directory</strong>
</p>

<p>
	In the second example, the goal is to make user home directories stored on the host available on client servers, while allowing trusted administrators of those client servers the access they need to conveniently manage users.
</p>

<p>
	To do this, you’ll export the /home directory. Since it already exists, you don’t need to create it. You won’t change the permissions, either. If you did, it could lead to a range of issues for anyone with a home directory on the host machine.
</p>

<p>
	<strong>Step 3 — Configuring the NFS Exports on the Host Server</strong>
</p>

<p>
	Next, you’ll dive into the NFS configuration file to set up the sharing of these resources.
</p>

<p>
	On the host machine, open the /etc/exports file in your text editor with root privileges:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo nano /etc/exports</span></pre>

<p>
	The file has comments showing the general structure of each configuration line. The syntax is as follows:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">/etc/exports

directory_to_share client(share_option1,...,share_optionN)</span></pre>

<p>
	You’ll need to create a line for each of the directories that you plan to share. Be sure to change the client_ip placeholder shown here to your actual client public IP address:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">/etc/exports

/var/nfs/general client_ip(rw,sync,no_subtree_check) /home client_ip(rw,sync,no_root_squash,no_subtree_check)</span></pre>

<p>
	Here, you’re using the same configuration options for both directories with the exception of no_root_squash. Take a look at what each of these options mean:
</p>

<ul>
	<li>
		rw: This option gives the client computer both read and write access to the volume.
	</li>
	<li>
		sync: This option forces NFS to write changes to disk before replying. This results in a more stable and consistent environment since the reply reflects the actual state of the remote volume. However, it also reduces the speed of file operations.
	</li>
	<li>
		no_subtree_check: This option prevents subtree checking, which is a process where the host must check whether the file is actually still available in the exported tree for every request. This can cause many problems when a file is renamed while the client has it opened. In almost all cases, it is better to disable subtree checking.
	</li>
	<li>
		no_root_squash: By default, NFS translates requests from a root user remotely into a non-privileged user on the server. This was intended as security feature to prevent a root account on the client from using the file system of the host as root. no_root_squash disables this behavior for certain shares.
	</li>
</ul>

<p>
	When you are finished making your changes, save and close the file. Then, to make the shares available to the clients that you configured, restart the NFS server with the following command:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo systemctl restart nfs-kernel-server</span></pre>

<p>
	Before you can actually use the new shares, however, you’ll need to be sure that traffic to the shares is permitted by firewall rules.
</p>

<p>
	<strong>Step 4 — Creating Mount Points and Mounting Directories on the Client</strong>
</p>

<p>
	Now that the host server is configured and serving its shares, you’ll prepare your client.
</p>

<p>
	In order to make the remote shares available on the client, you need to mount the directories on the host that you want to share to empty directories on the client.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">Note: If there are files and directories in your mount point, they will become hidden as soon as you mount the NFS share. To avoid the loss of important files, be sure that if you mount in a directory that already exists that the directory is empty.</span></pre>

<p>
	You’ll create two directories for your mounts on the client machine:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo mkdir -p /nfs/general
sudo mkdir -p /nfs/home</span></pre>

<p>
	Now that you have a location to put the remote shares and you’ve opened the firewall, you can mount the shares using the IP address of your host server:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo mount host_ip:/var/nfs/general /nfs/general
sudo mount host_ip:/home /nfs/home</span></pre>

<p>
	These commands will mount the shares from the host computer onto the client machine. You can double-check that they mounted successfully in several ways. You can check this with a mount or findmnt command, but the df -h command, which lists available disk space, provides a more readable output:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">df -h

Copy

Output

Output
Filesystem                   Size  Used Avail Use% Mounted on
tmpfs                        198M  972K  197M   1% /run
/dev/vda1                     50G  3.5G   47G   7% /
tmpfs                        989M     0  989M   0% /dev/shm
tmpfs                        5.0M     0  5.0M   0% /run/lock
/dev/vda15                   105M  5.3M  100M   5% /boot/efi
tmpfs                        198M  4.0K  198M   1% /run/user/1000
10.124.0.3:/var/nfs/general   25G  5.9G   19G  24% /nfs/general
10.124.0.3:/home              25G  5.9G   19G  24% /nfs/home</span></pre>

<p>
	Both of the shares you mounted appear at the bottom. Because they were mounted from the same file system, they show the same disk usage. To see how much space is actually being used under each mount point, use the disk usage command du and the path of the mount. The -s flag provides a summary of usage rather than displaying the usage for every file. The -h prints human-readable output.
</p>

<p>
	For example:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">du -sh /nfs/home

Output
36K /nfs/home</span></pre>

<p>
	This shows us that the contents of the entire home directory is using only 36K of the available space.
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">19</guid><pubDate>Tue, 14 Jan 2025 12:22:23 +0000</pubDate></item><item><title>Google Search Achievements</title><link>https://phoenix.lol/index.php?/blogs/entry/18-google-search-achievements/</link><description><![CDATA[<p>
	New achievement 800
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_11/google-search-800.png.a42b23ba41dff61fe1889f5dab966dad.png" data-fileid="211" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="211" data-ratio="108.70" width="690" alt="google-search-800.thumb.png.552df588910a847719714c60cb5dd2b9.png" data-src="https://phoenix.lol/uploads/monthly_2024_11/google-search-800.thumb.png.552df588910a847719714c60cb5dd2b9.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>
]]></description><guid isPermaLink="false">18</guid><pubDate>Sun, 10 Nov 2024 22:30:09 +0000</pubDate></item><item><title>Configuring Network Time Protocol (NTP) Client on Debian 12</title><link>https://phoenix.lol/index.php?/blogs/entry/17-configuring-network-time-protocol-ntp-client-on-debian-12/</link><description><![CDATA[<p>
	For software developers and system administrators, maintaining accurate system time is critical for ensuring that applications function correctly, especially in distributed systems where synchronization matters. The Network Time Protocol (NTP) serves as the backbone for time synchronization across computer systems. This article guides you through the process of configuring an NTP client on a Debian 12 system.
</p>

<p>
	<strong>Step 1: Installing NTP Software</strong>
</p>

<p>
	The first step is to install the NTP software package. Debian 12 provides an easy-to-use package management system. You can install NTP using the following command:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo apt-get update
sudo apt-get install ntp</span></pre>

<p>
	<strong>Step 2: Configuring NTP</strong>
</p>

<p>
	After installation, the next step is to configure the NTP client. The main configuration file for NTP is located at /etc/ntp.conf. Open this file with your preferred text editor, such as nano or vim:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo nano /etc/ntp.conf</span></pre>

<p>
	Within the configuration file, you can specify multiple NTP servers to synchronize with. It's recommended to choose servers that are geographically close to reduce latency. Replace or add servers in the configuration file:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">server 0.debian.pool.ntp.org iburst 
server 1.debian.pool.ntp.org iburst 
server 2.debian.pool.ntp.org iburst 
server 3.debian.pool.ntp.org iburst</span></pre>

<p>
	The iburst keyword allows for quicker synchronization when the NTP service starts.
</p>

<p>
	<strong>Step 3: Managing the NTP Service</strong>
</p>

<p>
	After configuring the NTP client, you need to restart the NTP service for the changes to take effect:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo systemctl restart ntp</span></pre>

<p>
	To ensure that NTP starts on system boot, enable the service:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo systemctl enable ntp</span></pre>

<p>
	You can also check the status of the NTP service to verify that it's running properly:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo systemctl status ntp</span></pre>

<p>
	<strong>Step 4: Verifying Synchronization</strong>
</p>

<p>
	To confirm that your Debian system is correctly synchronized with the NTP servers, you can use the ntpq -p command, which shows the list of peers with which the NTP client is synchronized, along with various statistics:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">ntpq -p</span></pre>

<p>
	Look for asterisks (*) next to the server names, which indicate that your client is actively synchronized with that server.
</p>

<p>
	<strong>Conclusion</strong>
</p>

<p>
	Configuring NTP on Debian 12 is a straightforward process that ensures your systems maintain accurate time, which is vital for many applications and services. For teams that require expert support in setting up and maintaining such infrastructure, consider the value of a skilled professional. <a href="https://phoenix.lol/index.php?/profile/1-guy-fawkes/" rel="">Hire a remote DevOps engineer</a> to streamline your operations and keep your systems in sync.
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">17</guid><pubDate>Thu, 26 Sep 2024 14:10:21 +0000</pubDate></item><item><title>Guide for the Monero CLI wallet</title><link>https://phoenix.lol/index.php?/blogs/entry/16-guide-for-the-monero-cli-wallet/</link><description><![CDATA[<h1 style="background-color:#ffffff;color:#4c4c4c;font-size:2.3rem;padding:0px;">
	Guide for the Monero CLI wallet
</h1>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	<code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monero-wallet-cli</code><span> </span>is the wallet software shipped in the Monero archives. It is a console program, and manages an account. While a bitcoin wallet manages both an account and the blockchain, Monero separates these:<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monerod</code><span> </span>handles the blockchain, and<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monero-wallet-cli</code><span> </span>handles the account.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	This guide will show how to perform various operations with<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monero-wallet-cli</code>. The guide assumes you are using the most recent version of Monero and have already created an account according to the other guides.
</p>

<h2 style="background-color:#ffffff;color:#4c4c4c;font-size:1.75rem;padding:0px;text-align:left;">
	Overview
</h2>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	You can have a list of the most important commands by running<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">help</code>:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">Important commands:

"welcome" - Show welcome message.
"help all" - Show the list of all available commands.
"help &lt;command&gt;" - Show a command's documentation.
"apropos &lt;keyword&gt;" - Show commands related to a keyword.

"wallet_info" - Show wallet main address and other info.
"balance" - Show balance.
"address all" - Show all addresses.
"address new [&lt;label text with white spaces allowed&gt;]" - Create new subaddress.
"transfer &lt;address&gt; &lt;amount&gt;" - Send XMR to an address.
"show_transfers [in|out|pending|failed|pool]" - Show transactions.
"sweep_all &lt;address&gt;" - Send whole balance to another wallet.
"seed" - Show secret 25 words that can be used to recover this wallet.
"refresh" - Synchronize wallet with the Monero network.
"status" - Check current status of wallet.
"version" - Check software version.
"exit" - Exit wallet.

"donate &lt;amount&gt;" - Donate XMR to the development team.
</code></pre>
	</div>
</div>

<h2 style="background-color:#ffffff;color:#4c4c4c;font-size:1.75rem;padding:0px;text-align:left;">
	Checking your balance
</h2>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Since the blockchain handling and the wallet are separate programs, many uses of<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monero-wallet-cli</code><span> </span>need to work with the<span> </span><a href="https://www.getmonero.org/resources/moneropedia/daemon.html" rel="external nofollow" style="border-bottom:none;color:#000000;">daemon</a>. This includes looking for incoming transactions to your address. Once you are running both<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monero-wallet-cli</code><span> </span>and<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monerod</code>, enter<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">balance</code>.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Output:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">Currently selected account: [0] Primary account
Tag: (No tag assigned)
Balance: 7.499942880000, unlocked balance: 7.499942880000
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	In this example you're viewing the balance of your primary account (with index<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">[0]</code>).<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">Balance</code><span> </span>is your total balance. The<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">unlocked balance</code><span> </span>is the amount currently available to spend. Newly received transactions require 10 confirmations on the blockchain before being unlocked.
</p>

<h2 style="background-color:#ffffff;color:#4c4c4c;font-size:1.75rem;padding:0px;text-align:left;">
	Sending monero
</h2>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	You will need the standard address you want to send to (a long string starting with '4' or a '8'). The command structure is:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">transfer ADDRESS AMOUNT
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Replace<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">ADDRESS</code><span> </span>with the address you want to send to and<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">AMOUNT</code><span> </span>with how many monero you want to send.
</p>

<h2 style="background-color:#ffffff;color:#4c4c4c;font-size:1.75rem;padding:0px;text-align:left;">
	Receiving monero
</h2>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	If you have your own Monero address, you just need to give your address to someone.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	You can find out your primary address with:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">address
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Since Monero is anonymous, you won't see the origin address the funds you receive came from. If you want to know, for instance to credit a particular customer, you'll have to tell the sender to use a payment ID, which is an arbitrary optional tag which gets attached to a transaction. It's not possible to use standalone payment addresses, but you can generate an address that already includes a random payment ID (integrated addresss) using<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">integrated_address</code>:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">Random payment ID: &lt;82d79055f3b27f56&gt;
Matching integrated address: 4KHQkZ4MmVePC2yau6Mb8vhuGGy8LVdsZD8CFcQJvr4BSTfC5AQX3aXCn5RiDPjvsEHiJu1TC1ybR8pRTCbZM5bhTrAD3HDwWMtAn1K7nV
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	This will generate a random payment ID, and give you the address that includes your own account and that payment ID. If you want to select a particular payment ID, you can do that too. Use:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">integrated_address 82d79055f3b27f56
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Payments made to an integrated address generated from your account will go to your account, with that payment ID attached, so you can tell payments apart.
</p>

<h3 style="background-color:#ffffff;color:#4c4c4c;font-size:1.5rem;padding:1rem 0px 0px;">
	Using subaddresses
</h3>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	It's suggested to use subaddresses (starting with<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">8</code>) instead of your main address (starting with<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">4</code>) to receive funds. Run:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">address new [&lt;label text with white spaces allowed&gt;]
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	This will generate a subaddress and its optional label, which addess you can share to receive payment on the account it's linked to. For example,
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">address new github_donations
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	will generate a subaddress and its label 'github_donations'.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	To view all generated addresses, run:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">address all
</code></pre>
	</div>
</div>

<h2 style="background-color:#ffffff;color:#4c4c4c;font-size:1.75rem;padding:0px;text-align:left;">
	Proving to a third party you paid someone
</h2>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	If you pay a merchant, and the merchant claims to not have received the funds, you may need to prove to a third party you did send the funds - or even to the merchant, if it is a honest mistake. Monero is private, so you can't just point to your transaction in the blockchain, as you can't tell who sent it, and who received it. However, by supplying the per-transaction private key to a party, that party can tell whether that transaction sent monero to that particular address. Note that storing these per-transaction keys is disabled by default, and you will have to enable it before sending, if you think you may need it:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">set store-tx-info 1
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	You can retrieve the tx key from an earlier transaction:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">get_tx_key 1234567890123456789012345678901212345678901234567890123456789012
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Pass in the transaction ID you want the key for. Remember that a payment might have been split in more than one transaction, so you may need several keys. You can then send that key, or these keys, to whoever you want to provide proof of your transaction, along with the transaction id and the address you sent to. Note that this third party, if knowing your own address, will be able to see how much change was returned to you as well.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	If you are the third party (that is, someone wants to prove to you that they sent monero to an address), then you can check this way:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">check_tx_key TXID TXKEY ADDRESS
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	Replace<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">TXID</code>,<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">TXKEY</code><span> </span>and<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">ADDRESS</code><span> </span>with the transaction ID, per-transaction key, and destination address which were supplied to you, respectively.<span> </span><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">monero-wallet-cli</code><span> </span>will check that transaction and let you know how much monero this transaction paid to the given address.
</p>

<h2 style="background-color:#ffffff;color:#4c4c4c;font-size:1.75rem;padding:0px;text-align:left;">
	How to find a payment to you
</h2>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	If you received a payment using a particular payment ID, you can look it up:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">payments PAYMENTID
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	You can give more than one payment ID too.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	More generally, you can review incoming and outgoing payments:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">show_transfers
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	You can give an optional height to list only recent transactions, and request only incoming or outgoing transactions. For example,
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">show_transfers in 650000
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	will only show incoming transfers after block 650000. You can also give a height range.
</p>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	If you want to mine, you can do so from the wallet:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">start_mining 2
</code></pre>
	</div>
</div>

<p style="background-color:#ffffff;color:#4c4c4c;font-size:1.0625rem;padding:1rem 0px 0px;">
	This will start mining on the daemon usin two threads. Note that this is solo mining, and may take a while before you find a block. To stop mining:
</p>

<div style="background-color:#ffffff;color:#4c4c4c;font-size:medium;">
	<div>
		<pre style="background-color:#fff1e8;color:#2f6f9f;padding:0.7rem;"><code style="background-color:#fff1e8;color:#2f6f9f;padding:0.2rem;">stop_mining
</code></pre>
	</div>
</div>
]]></description><guid isPermaLink="false">16</guid><pubDate>Wed, 25 Sep 2024 20:32:43 +0000</pubDate></item><item><title>Journals</title><link>https://phoenix.lol/index.php?/blogs/entry/15-journals/</link><description><![CDATA[<p>
	Today, at the request of a user, I made a section with magazines!<br />
	If you want to add magazines, write me a private message with the names of the sections that need to be created!
</p>

<p>
	<a href="https://phoenix.lol/index.php?/forum/80-journals-en/" rel="">https://phoenix.lol/index.php?/forum/80-journals-en/</a>
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">15</guid><pubDate>Sun, 01 Sep 2024 16:52:33 +0000</pubDate></item><item><title>Understanding Redis</title><link>https://phoenix.lol/index.php?/blogs/entry/14-understanding-redis/</link><description><![CDATA[<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="151" data-ratio="52.25" width="844" alt="redis-logo.png.1095dc4ac3f5e36283fe14fd565555bd.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-logo.png.1095dc4ac3f5e36283fe14fd565555bd.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<strong>What is Redis?</strong><br />
	Redis (Remote Dictionary Service) is an open source key-value database server.
</p>

<p>
	The most accurate way to describe Redis is to say that it is a data structure server. The unique features of the Redis server have become the main reason for its popularity and the fact that it is used in many real projects.
</p>

<p>
	Instead of working with database rows, iterating, sorting, ordering them, what if the information is initially in the data structures that the programmer needs? At first, Redis was used almost the same way as Memcached. But, as Redis evolved, this database management system (DBMS) found application in many other situations. In particular, in the implementation of the publisher/subscriber mechanism, in streaming data processing tasks, in systems where it is necessary to work with queues.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-1.jpeg.b44ec66e8bb3b56bcd04a0582be00485.jpeg" data-fileid="142" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="142" data-ratio="132.74" width="565" alt="redis-1.thumb.jpeg.565009a561a4d853295353503ccd04d9.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-1.thumb.jpeg.565009a561a4d853295353503ccd04d9.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	Here are the data types supported by Redis:
</p>

<ul>
	<li>
		String
	</li>
	<li>
		Bitmap
	</li>
	<li>
		Bitfield
	</li>
	<li>
		Hash
	</li>
	<li>
		List
	</li>
	<li>
		Set
	</li>
	<li>
		Sorted set
	</li>
	<li>
		Geospatial
	</li>
	<li>
		HyperLogLog structure
	</li>
	<li>
		Stream
	</li>
</ul>

<p>
	Redis is an in-memory database that is used primarily as a cache in front of another, "real" database, such as MySQL or PostgreSQL. A cache based on Redis helps improve application performance. It leverages the data speed of memory and alleviates the load on the application's central database for the following data:
</p>

<ul>
	<li>
		Data that rarely changes and is accessed frequently by the application.
	</li>
	<li>
		Non-mission-critical data that changes frequently.
	</li>
</ul>

<p>
	Examples of such data may include session or data caches, as well as dashboard content such as leaderboards and reports that include data aggregated from different sources.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-2.jpeg.bcbc9dda6e5cf7f1a1db791cde6e3d21.jpeg" data-fileid="143" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="143" data-ratio="55.10" width="1000" alt="redis-2.thumb.jpeg.1d79730778b241b25b1d9dbdc67533aa.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-2.thumb.jpeg.1d79730778b241b25b1d9dbdc67533aa.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<em>The traditional approach to using Redis is as follows: the client accesses the application, and it receives the data necessary to fulfill its request. First (item 1 in the figure), the application accesses the Redis cache, represented by the main database (Main). If the cache contains data, a cache hit occurs, and the data is returned as usual. If a cache miss occurs (item 2), the system accesses the persistent storage (in this case, the MySQL database). The data from it (item 3) is loaded into the cache, after which the application can use it.</em>
</p>

<p>
	But in many cases, Redis guarantees a high enough level of data safety that it can be used as a true primary database. And adding Redis plugins and various High Availability (HA) configurations to the system makes the Redis database extremely interesting for certain use cases and workloads.
</p>

<p>
	Another important feature of Redis is that it blurs the boundaries between cache and data storage. It is important to understand that reading data from memory and working with data in memory is much faster than the same operations performed by traditional DBMSs using regular hard disk drives (HDD) or solid-state drives (SSD).
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-3.jpeg.1b3e4f70bb92a97d72d9dd173d99780e.jpeg" data-fileid="144" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="144" data-ratio="70.60" width="1000" alt="redis-3.thumb.jpeg.3d211cab2be1d1ba44610b8aff53bce6.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-3.thumb.jpeg.3d211cab2be1d1ba44610b8aff53bce6.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<em>Latency and throughput characteristics of systems that every programmer should know.</em>
</p>

<p>
	Initially, Redis was most often compared to Memcached, a system that at that time had no hint of long-term data storage.
</p>

<p>
	Memcached was created in 2003 by Brad Fitzpatrick. It appeared 6 years before Redis. At first, it was a Perl project, and later it was rewritten in C. At one time, Memcached was a standard caching tool. The main differences between it and Redis are that Memcached has fewer data types and limitations related to the key eviction policy. Memcached only supports the LRU (Least Recently Used) policy, when the data that has not been used for the longest time is evicted first.
</p>

<p>
	Another difference between these storages is that Redis is a single-threaded system, and Memcached is multi-threaded. Memcached can show excellent performance results in limited caching environments. And when using this system in a distributed cluster, additional settings are required. Redis supports such scenarios right out of the box.
</p>

<p>
	The following table provides information on the differences between Memcached and Redis that are relevant today.
</p>

<p>
	Nowadays, Redis supports customization of how exactly data is saved to disk. In the very beginning, the system used snapshots, when asynchronous copies of data located in memory were sent to disk for long-term storage. Unfortunately, this mechanism has a drawback, expressed in the possible loss of data changed or added to the storage in the time intervals between snapshots.
</p>

<p>
	Redis has evolved significantly since its inception in 2009. We will cover most of the architectural and topological decisions specific to Redis, which will allow you to study this system and include it in your arsenal of data storage systems.
</p>

<p>
	<strong>Redis Architecture</strong><br />
	Before we start talking about the internal mechanisms of Redis, let's look at the different options for deploying this storage and discuss the trade-offs that those who choose one or another option have to make.
</p>

<p>
	We will mainly focus on the following configurations:
</p>

<ul>
	<li>
		Single Redis instance.
	</li>
	<li>
		Redis HA.
	</li>
	<li>
		Redis Sentinel.
	</li>
	<li>
		Redis Cluster.
	</li>
</ul>

<p>
	You can choose one or another configuration depending on the specifics of your project and its scale.
</p>

<p>
	Single Redis instance
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="145" data-ratio="55.81" width="869" alt="redis-4.png.3413119a5bf58218a93440ead85f8591.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-4.png.3413119a5bf58218a93440ead85f8591.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<em>A simple Redis deployment option, represented by a single Main database.</em>
</p>

<p>
	The simplest way to deploy Redis is to use a single instance of the system. With this approach, the user has a small storage at their disposal that will help the project grow and develop and speed up the services of this project. But this way of using Redis also has its drawbacks. For example, if the Redis instance used in the project fails or becomes unavailable, all client requests to Redis will fail, resulting in a drop in overall performance and system speed.
</p>

<p>
	If you give the Redis instance enough memory and server resources, this instance can turn out to be quite a powerful entity. This approach is mainly used for caching, and allows you to get a serious increase in project performance by spending a minimum of effort and time on setting up the system. If you have sufficient server resources, you can deploy such a Redis service on the same machine where the main application is running.
</p>

<p>
	To work successfully with Redis, it is important to understand some of the concepts of the system related to data management. Requests to the Redis database are processed by working with data stored in memory. If the Redis instance being used provides for the use of persistent data storage, the system will have a fork of the process. It uses the RDB (Redis Database) to organize persistent storage of snapshots of data. This is a very compact representation of Redis data at a certain point in time. Instead of RDB, files intended only for appending data (Append-Only File, AOF) can be used.
</p>

<p>
	These two mechanisms allow Redis to have a long-term data storage, support various replication strategies, and help to implement more complex topologies based on Redis. If the Redis server is not configured for persistent data storage, then upon a reboot or system failure, the data is lost. If persistent storage is enabled, then upon a system reboot, the data from the RDB snapshot or from the AOF is loaded into memory. After that, the Redis instance will be able to process client requests.
</p>

<p>
	Given the above, let's consider Redis configurations that are characterized, so to speak, by greater distribution than the one considered.
</p>

<p>
	Redis HA
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="146" data-ratio="55.09" width="864" alt="redis-5.png.365ccd54447aa7f235a42a2557782493.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-5.png.365ccd54447aa7f235a42a2557782493.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	<em>High availability configuration. The system consists of a main database (Main), the leading node, and a secondary database (Secondary), the slave node. The state of the nodes is synchronized by replication.</em>
</p>

<p>
	Another popular Redis configuration is a system consisting of a master and slave nodes, whose state is synchronized through replication. As data is written to the master Redis instance, copies of the corresponding commands are sent to the output buffer of the slave nodes, ensuring that the data is replicated. Slaves can contain one or more Redis instances. These instances can help scale data reads or provide fault tolerance for the system in the event of loss of communication with the master node.
</p>

<p>
	High Availability (HA) is a characteristic of a system that aims to provide a consistent level of its performance (usually system uptime) over longer-than-average time intervals.
</p>

<p>
	High availability systems are designed to have no single point of failure. This allows them to gracefully and quickly recover from failures. High availability configurations require reliable communication links, which eliminates the possibility of data loss during transmission from the master to the slave node. In addition, such systems automatically detect and recover from failures.
</p>

<p>
	As we now move into distributed systems, which are associated with many misconceptions, we need to become familiar with a few new concepts. What was once simple and straightforward is now becoming more complex.
</p>

<p>
	Data Replication in Redis<br />
	Each Redis master node has an ID and a replication offset. These two metrics are extremely important to determine when a slave node can continue the replication process or when a full data synchronization is needed. The offset is incremented by any action that occurs on the Redis master node.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">Replication ID, offset</span></pre>

<p>
	To be more specific, when a Redis slave is only a few offset steps behind the master, it receives outstanding commands from the master, applies those commands to the data, and so on until the nodes are synchronized. If the two instances cannot agree on a replication ID, or the master has no offset information, the slave requests a full data synchronization. This involves the master creating a new RDB snapshot and sending it to the slave. While sending this data, the master buffers the intermediate data updates that occurred between the snapshot creation and the current time. These updates will be sent to the slave after it synchronizes with the snapshot. Once this process is complete, replication can continue as normal.
</p>

<p>
	If different Redis instances have the same ID and offset, it means that they are storing exactly the same data. This may raise the question of why Redis uses a replication ID. The point is that when a Redis instance is promoted to a master, or if an instance is started as a master right away, it is assigned a new replication ID. This is used to figure out which Redis instance was the master before. Specifically, it figures out which instance the node that was just promoted was previously copying data from. This allows for partial synchronization (with other slaves) to occur, since the new master remembers its old replication ID.
</p>

<p>
	For example, two Redis instances, a master and a slave, have the same replication ID, but their offsets differ by several hundred commands. That is, if we replay the corresponding commands on the “lagging” instance, both instances will have an identical set of data. Suppose that the replication IDs of the instances are different and we do not know the previous ID (the instances do not have a common ancestor) of the node that was recently demoted to a slave (it is connected to the master). In such a situation, we need to perform a resource-intensive full data synchronization operation.
</p>

<p>
	On the other hand, if the previous replication ID is known, we can think about how to synchronize the data of the two nodes. Since we know the common ancestor of the nodes, this means that they store common data, and therefore, using the offset, we can perform partial data synchronization.
</p>

<p>
	<strong>Redis Sentinel</strong>
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-6.png.60db92061d472b562695764a2aeba1bc.png" data-fileid="147" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="147" data-ratio="111.28" width="674" alt="redis-6.thumb.png.47dae0f4e65589309f41ca7a7ea9e084.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-6.thumb.png.47dae0f4e65589309f41ca7a7ea9e084.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<em>Deploying a system using Redis Sentinel. This deployment consists of Sentinel nodes, a master node, and slave nodes.</em>
</p>

<p>
	Redis Sentinel is a service that enables the creation of distributed systems. And, as with all distributed systems, Sentinel has its strengths and weaknesses. Sentinel is based on a cluster of Sentinel processes working together. They coordinate the state of the system, implementing a high-availability configuration for Redis. Sentinel is a service that protects the Redis storage from failures. Therefore, it is logical that this service should not have a single point of failure.
</p>

<p>
	The Sentinel service solves several problems. First, it ensures the operability and availability of the current master and slave nodes. Thanks to this, the current Sentinel process (along with other similar processes) can react to a situation when communication with the master and/or slave nodes is lost. Second, it plays a certain role in service discovery. Zookeeper and Consul work in a similar way in other systems. That is, when a new client tries to write something to the Redis store, Sentinel will tell the client which Redis instance is currently the master.
</p>

<p>
	So Sentinel nodes constantly monitor the availability of Redis instances and send information about them to clients, which allows clients to take certain actions in cases where the store fails.
</p>

<p>
	Here are the functions that Sentinel nodes perform:
</p>

<ol>
	<li>
		Monitoring: Ensure that master and slave nodes are operating as expected.
	</li>
	<li>
		Sending notifications to administrators: The system sends notifications to administrators about incidents in Redis instances.
	</li>
	<li>
		Managing failover: Sentinel nodes can initiate a failover process if the master Redis instance is unavailable and a sufficient number (quorum) of nodes agree that this is the case.
	</li>
	<li>
		Configuration management: Sentinel nodes also act as a system that allows the current master Redis instance to be discovered.
	</li>
</ol>

<p>
	Using Redis Sentinel to solve the above problems allows you to detect Redis failures. The failure detection procedure involves getting agreement from multiple Sentinel nodes that the current master Redis instance is unavailable. The process of getting such agreement is called a quorum. This allows you to increase the reliability of the system, protect against situations where one of the processes behaves incorrectly and cannot connect to the master Redis node.
</p>

<p>
	A quorum is the minimum number of votes that a distributed system needs to receive in order to be allowed to perform certain operations, such as failover. This number is configurable, but it should reflect the number of nodes in the distributed system in question. Most distributed systems are three or five nodes in size, in which case the quorum is two or three votes. Odd numbers of nodes are preferable in cases where the system needs to resolve ambiguities.
</p>

<p>
	Redis Sentinel also has its drawbacks. Therefore, we will look at some recommendations and practical tips regarding this service.
</p>

<p>
	Redis Sentinel can be deployed in a number of ways. Honestly, I'd need details about the setup you plan to use Redis Sentinel in to give any meaningful recommendations. As a general rule, I'd recommend running a Sentinel node alongside each of your application servers (if possible). This will eliminate network connectivity differences between Sentinel nodes and clients running Redis.
</p>

<p>
	Sentinel can also be run on the same machines as Redis instances, or even as independent nodes, but this complicates things in various ways. I recommend using at least three nodes with a quorum of at least two. Here's a simple table that describes the number of servers in the cluster, quorum information, and the number of failures allowed.
</p>

<p>
	These metrics will vary from system to system, but the general idea is similar to what is expressed in the table.
</p>

<p>
	Think about what could go wrong in a system running Sentinel. If such a system is run long enough, you could run into all of these problems.
</p>

<ol>
	<li>
		What if the Sentinel nodes fall out of quorum?
	</li>
	<li>
		What if the network splits and the old master Redis instance ends up in a smaller group of Sentinel nodes? What happens to the data written to that Redis instance? (Hint: this data will be lost after a full system recovery.)
	</li>
	<li>
		What happens if the network topologies of the Sentinel nodes and the client (application) nodes are inconsistent?
	</li>
</ol>

<p>
	There are no guarantees for system resiliency, especially since writes to disk (more on that below) are asynchronous. There's also the pesky issue of when clients learn about new leaders. How many writes will go to waste if the new leader is unknown? The Redis developers recommend querying for the new leader when establishing new connections. Depending on your system configuration, this can lead to significant data loss.
</p>

<p>
	There are a few ways to mitigate this data loss by forcing the Redis master to replicate writes to at least one slave. Remember that replication in Redis is asynchronous, and that it has its own drawbacks. You'll need to track acknowledgments independently, and if you can't get an acknowledgment from at least one slave, the master should stop accepting writes.
</p>

<p>
	<strong>Redis Cluster</strong>
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-7.jpeg.8e210b47c9da300ab644f3509c5c161c.jpeg" data-fileid="148" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="148" data-ratio="60.60" width="1000" alt="redis-7.thumb.jpeg.1325d5b7c4af36f61683eb6ea0e51257.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-7.thumb.jpeg.1325d5b7c4af36f61683eb6ea0e51257.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<em>Redis cluster. Clients perform read/write operations by interacting with Redis master (M1, M2, M3) nodes. Data is replicated between master and slave (S1, S2, S3) nodes. Other clients perform data read operations by accessing slave nodes. The Gossip protocol is used to determine the overall state of the cluster.</em>
</p>

<p>
	I'm sure many people are wondering what to do if they can't store all the necessary data in memory on a single machine. These days, the maximum amount of RAM available on a single server is 24 TiB, and AWS has such configurations. Of course, this is a lot, but for some systems, this is not enough even for organizing a cache.
</p>

<p>
	Redis Cluster allows you to horizontally scale Redis storage.
</p>

<p>
	As a system grows, its owner can choose one of the following three options:
</p>

<ol>
	<li>
		Work less (nobody does this, because we are insatiable monsters).
	</li>
	<li>
		Increase the power of individual computers.
	</li>
	<li>
		Distribute the load across more small computers.
	</li>
</ol>

<p>
	We will only take the last two items on this list seriously. They are known as vertical and horizontal scaling, respectively. Vertical scaling uses more advanced computers to speed up the system, hoping that the increased computing power will allow it to successfully cope with the growing load. But even if the expectations are met at first, eventually the one using vertical scaling will face the limitations of the hardware.
</p>

<p>
	After vertical scaling has exhausted itself (and most likely, hopefully, long before that), it will be necessary to turn to horizontal scaling. This is the distribution of the load across many small machines responsible for solving small subtasks of one large task.
</p>

<p>
	Let's get the terminology straight. Once we decide to use Redis Cluster, this means that we decide to distribute the data we store across many machines. This is called sharding. As a result, each Redis instance in the cluster is considered to store a shard, or fragment, of all the data.
</p>

<p>
	This approach brings to life a new problem. If you send data to the cluster, how do you know which Redis instance (shard) stores this data? There are several ways to do this. Redis Cluster uses algorithmic sharding.
</p>

<p>
	In order to find a shard for a given key, we hash the key and divide the result modulo the number of shards. Then, using a deterministic hash function (thanks to which a specific key will always correspond to the same shard), when we need to read the corresponding data, we can find out where exactly it is stored.
</p>

<p>
	What happens if a new shard is added to the system after some time? What happens is called resharding.
</p>

<p>
	Assuming that the foo key was assigned to shard 0, it can be resharded to shard 5. But moving data around to fit the new shard configuration is slow and unrealistic if we want storage expansion operations to be fast. Moving data around like this will also have a negative impact on the availability of Redis Cluster.
</p>

<p>
	Redis Cluster has a mechanism to solve this problem. These are the so-called "hash slots" where data is sent. There are about 16,000 of these slots. This gives us an adequate way to distribute data across the cluster, and when adding new shards, we just need to move hash slots around the system. By doing this, we only need to move hash slots from shard to shard and simplify the process of adding new master Redis instances to the cluster.
</p>

<p>
	This can be done without any system downtime and with minimal impact on its performance. Let's look at an example.
</p>

<p>
	Node M1 contains hash slots from 0 to 8191.
</p>

<p>
	Node M2 contains hash slots from 8192 to 16383.
</p>

<p>
	When assigning a hash slot to key foo, we calculate the deterministic hash of the key (foo) and divide it modulo the number of hash slots (16383). As a result, the data corresponding to this key goes to node M2. Now, suppose we add a new node to the system - M3. The new mapping of nodes and hash slots will be as follows:
</p>

<p>
	Node M1 contains hash slots 0 through 5460.
</p>

<p>
	Node M2 contains hash slots 5461 through 10922.
</p>

<p>
	Node M3 contains hash slots 10923 through 16383.
</p>

<p>
	All keys that were in node M1's hash slots, now belonging to node M2, would need to be moved. But the correspondence between individual keys and hash slots is preserved, since the keys are already distributed across hash slots. Thus, this mechanism solves the resharding problem when using algorithmic sharding.
</p>

<p>
	<strong>Gossip Protocol</strong><br />
	Redis Cluster uses the Gossip protocol to determine the overall health of the cluster. In the above illustration, there are 3 master (M) nodes and 3 slave (S) nodes. All of these nodes are constantly communicating with each other to know which shards are available and ready to handle requests. If enough shards agree that node M1 is not responding to requests, they may decide to promote S1, M1's slave, to the master rank to keep the cluster alive. The number of nodes required to run this procedure is configurable. It is very important to get this setup right. If you get it wrong, you could end up with a cluster that is split into pieces if it cannot resolve an ambiguous situation where the same number of systems vote for and against it. This phenomenon is called a "split brain". Therefore, as a general rule, it is important to have an odd number of master nodes in the cluster, each with two slave nodes. This will serve as a good basis for building a reliable system.
</p>

<p>
	Redis Persistence Models<br />
	If you plan to store any data in Redis with the expectation that it will be stored reliably, it is important to understand how Redis does this. There are many situations where losing data stored in Redis is not such a big deal. For example, using Redis as a cache, or in situations where Redis stores data for some real-time analytics system.
</p>

<p>
	In other cases, developers need some guarantees about the persistence of data and the ability to recover it.
</p>

<p>
	Redis is a fast store, and any guarantees about data integrity are secondary to speed. This may be a controversial topic, but it is true.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-8.jpeg.b99009b51dbb8efd14a848647cdd600c.jpeg" data-fileid="149" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="149" data-ratio="20.60" width="1000" alt="redis-8.thumb.jpeg.afb5e14788a21712ddb357e57024ba39.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-8.thumb.jpeg.afb5e14788a21712ddb357e57024ba39.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<em>Persistent storage models in Redis. Data from memory is copied either to RDB, as snapshots, or to AOF. If a Redis instance fails but the instance's data was stored in persistent storage, that data is loaded into a new Redis instance.</em>
</p>

<p>
	Persistent data storage is not used<br />
	If necessary, persistent data storage can be disabled. This is the configuration when using Redis, which works the fastest, but does not guarantee reliable data storage.
</p>

<p>
	RDB files<br />
	Persistent data storage in RDB files implies the creation of snapshots containing data relevant at certain points in time. Snapshots are created at specified time intervals.
</p>

<p>
	The main disadvantage of this mechanism is that data received in the storage between the moments of snapshot creation will be lost if Redis fails. In addition, this data storage mechanism relies on creating a fork of the main process. When working with large data sets, this can lead to short-term delays in query processing. However, RDB files are loaded into memory much faster than AOF.
</p>

<p>
	AOF<br />
	The persistent storage mechanism based on AOF logs every write operation that the server receives a request to perform. These operations will be replayed when the server starts, which will recreate the original data set.
</p>

<p>
	This approach to persistent data storage is much more reliable than RDB. After all, we are not talking about snapshots of the storage state, but about files designed only for data to be appended to them. When operations occur, they are buffered in the journal, but they are not immediately placed in the persistent storage. The journal contains the actual commands that, if data needs to be restored, are run in the order in which they were executed.
</p>

<p>
	Then, when possible, the journal is flushed to disk using fsync (the exact time of this process can be configured). After that, the data is in the persistent storage. The downside of this approach is that this data storage format is not compact, it requires more disk space than RDB files.
</p>

<p>
	The fsync() call transfers ("flushes") all modified data from memory (that is, modified file buffer pages) related to the file represented by the file descriptor fd to the disk device (or other device for permanent storage of information). As a result, all modified information can be restored even after a serious failure or reboot of the system.
</p>

<p>
	For various reasons, changes made to an open file first go to the cache, and the fsync() call ensures that they are physically saved to the disk, that is, they can be read from the disk later.
</p>

<p>
	Why not use both RDB and AOF?<br />
	You can combine AOF and RDB in the same Redis instance. If you are okay with the reliability of storing data in exchange for some speed reduction, you can do so. I think this is an acceptable way to use Redis. However, if the system is rebooted, remember that Redis will use AOF to restore data, since this storage contains a more complete version of the data.
</p>

<p>
	Forking Redis processes<br />
	Now that we have covered the mechanisms of organizing persistent data storage in Redis, let's talk about how this is done in a single-threaded application like Redis.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/redis-9.jpeg.56bbafb7a6fe0922bdce51010849cad0.jpeg" data-fileid="150" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="150" data-ratio="74.90" width="1000" alt="redis-9.thumb.jpeg.0ccd115309324f0bf57e36503fd9e42c.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/redis-9.thumb.jpeg.0ccd115309324f0bf57e36503fd9e42c.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<em>Creates a fork of the Redis process. The snapshot contains data relevant at a certain point in time. After the fork is created, the data is copied to disk.</em>
</p>

<p>
	I think the best thing about Redis is how it uses forking and copy-on-write to implement high-performance copying of data to persistent storage.
</p>

<p>
	A fork is when the operating system, on command from a process, creates a new process by copying the parent process. As a result, we have a new process ID and some other useful information at our disposal. In this case, the newly created fork of the process (the child process) can interact with the parent process.
</p>

<p>
	Now comes the fun part. Redis is a process that has a huge amount of memory allocated. How can we copy such a process and not run out of memory?
</p>

<p>
	When a process is forked, the parent and child processes share memory. Redis starts the process of creating a snapshot in the child process. This is possible thanks to a memory sharing technique called “copy-on-write”. In this case, no memory is allocated during the fork, but references to already allocated memory are used. If nothing in memory has changed when the child process flushes data to disk, no new memory will be allocated.
</p>

<p>
	If there have been changes, the following happens. The operating system kernel tracks references to each memory page. If there is more than one reference to a page, the changes are written to new pages. The child process knows nothing about the changes; it has a stable snapshot of memory at its disposal. As a result, only a small amount of memory is used to create a fork of the process. We can quickly and efficiently create snapshots that reflect the state of the storage at a certain point in time, the size of which can reach many gigabytes.
</p>

<p>
	<strong>Summary</strong><br />
	We've covered various issues related to the fast, in-memory Redis data store. If you haven't worked with this storage before, but after reviewing its capabilities, you realize that it might be useful to you, we recommend <a href="https://redis.io/" rel="external nofollow">visiting the project's website</a> and trying out Redis in action.
</p>
]]></description><guid isPermaLink="false">14</guid><pubDate>Wed, 14 Aug 2024 14:53:48 +0000</pubDate></item><item><title>&#x41E;&#x431;&#x437;&#x43E;&#x440; Trustee Plus: &#x43A;&#x43E;&#x448;&#x435;&#x43B;&#x435;&#x43A; &#x441;&#x43E; &#x432;&#x441;&#x442;&#x440;&#x43E;&#x435;&#x43D;&#x43D;&#x43E;&#x439; &#x43A;&#x440;&#x438;&#x43F;&#x442;&#x43E;&#x432;&#x430;&#x43B;&#x44E;&#x442;&#x43D;&#x43E;&#x439; &#x43A;&#x430;&#x440;&#x442;&#x43E;&#x439;</title><link>https://phoenix.lol/index.php?/blogs/entry/13-%D0%BE%D0%B1%D0%B7%D0%BE%D1%80-trustee-plus-%D0%BA%D0%BE%D1%88%D0%B5%D0%BB%D0%B5%D0%BA-%D1%81%D0%BE-%D0%B2%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9-%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2%D0%B0%D0%BB%D1%8E%D1%82%D0%BD%D0%BE%D0%B9-%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B9/</link><description><![CDATA[<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/TRUSTEE-PLUS.jpg.65ce25bcefb4c8b06249cffd6954cbaf.jpg" data-fileid="111" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="111" data-ratio="61.50" width="1000" alt="TRUSTEE-PLUS.thumb.jpg.1fd9f35c058a603b09da8250e7d5dff3.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/TRUSTEE-PLUS.thumb.jpg.1fd9f35c058a603b09da8250e7d5dff3.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<strong>Что в этой статье?:</strong>
</p>

<ul>
	<li>
		1. Что нужно для регистрации и KYC
	</li>
	<li>
		2. Покупка, обмен и переводы криптовалют
	</li>
	<li>
		3. Мониторинг рынка
	</li>
	<li>
		4. Криптовалютная карта и ее возможности
	</li>
	<li>
		5. Реферальная программа для сообщества
	</li>
	<li>
		6. Выводы
	</li>
</ul>

<p>
	Мобильное приложение <a href="https://trusteeglobal.com/ru/?r=fbx5UMZvdGb" rel="external nofollow">Trustee Plus</a> появилось на рынке в июле 2022 года и является одним из трех продуктов экосистемы Trustee. Разработчики позиционируют проект как платформу цифровых финансов.
</p>

<p>
	Функциональные возможности Trustee Plus выходят за пределы стандартных криптокошельков. Помимо хранения, обмена и покупки криптовалют, пользователям доступен вывод активов напрямую на банковские карты. Trustee Plus также позволяет отслеживать ситуацию на рынке и предлагает реферальную программу для активных клиентов.
</p>

<p>
	В августе 2023 года приложение возглавило рейтинг украинского App Store в разделе «Финансы». А через месяц команда заявила, что количество активных пользователей в Украине превысило 100 000 человек.
</p>

<p>
	Редакция Phoenix.lol протестировала платформу по управлению цифровыми активами Trustee Plus и подготовила детальный обзор приложения.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://trusteeglobal.com/ru/?r=fbx5UMZvdGb" rel="external nofollow"><img class="ipsImage ipsImage_thumbnailed" data-fileid="112" data-ratio="11.80" width="1000" alt="---.thumb.png.30b73c1754dfeb505d69f6b8299eee32.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/---.thumb.png.30b73c1754dfeb505d69f6b8299eee32.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<strong>Что нужно для регистрации и KYC</strong>
</p>

<p>
	Trustee Plus работает под управлением iOS (<a href="https://trusteeglobal.com/ru/?r=fbx5UMZvdGb" rel="external nofollow">скачать</a>) и Android (<a href="https://trusteeglobal.com/ru/?r=fbx5UMZvdGb" rel="external nofollow">скачать</a>). Чтобы пользоваться приложением, необходимо зарегистрироваться по номеру телефона и ввести код из SMS. Все это занимает около минуты.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/1-register_step_1_ru.jpg.4de4d1d16ef9f3b3d11c896bc448f9ce.jpg" data-fileid="113" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="113" data-ratio="216.76" width="346" alt="1-register_step_1_ru.thumb.jpg.431aea9ef5b3e186fe1c81b83685a9b4.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/1-register_step_1_ru.thumb.jpg.431aea9ef5b3e186fe1c81b83685a9b4.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/2-register_step_2_ru.jpg.33c233b9bcc1011c22fc773c30b337f5.jpg" data-fileid="114" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="114" data-ratio="216.76" width="346" alt="2-register_step_2_ru.thumb.jpg.41b939ee90c5a4bf58a9ffa677db000c.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/2-register_step_2_ru.thumb.jpg.41b939ee90c5a4bf58a9ffa677db000c.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	Экран регистрации в приложении. Данные: Trustee Plus.
</p>

<p>
	Сразу после регистрации приложение запрашивает доступ к контактам для осуществления мгновенных переводов по номеру телефона, а также просит разрешение на использование камеры. Это необязательно, пользователь может не давать согласия. При необходимости его можно предоставить позже.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="115" data-ratio="74.96" width="591" alt="sign-up-trustee-plus-3-edited.jpg.870b083a3f31944c11fcdc211c7175ce.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/sign-up-trustee-plus-3-edited.jpg.870b083a3f31944c11fcdc211c7175ce.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /> <img class="ipsImage ipsImage_thumbnailed" data-fileid="116" data-ratio="74.96" width="591" alt="sign-up-trustee-plus-4-edited.jpg.00f049797bdae57ef58e4ebe557bd8f3.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/sign-up-trustee-plus-4-edited.jpg.00f049797bdae57ef58e4ebe557bd8f3.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p style="text-align:center;">
	Запрашиваемые Trustee Plus доступы. Данные: Trustee Plus.
</p>

<p>
	Кроме этого пользователь обязан пройти верификацию. Процедуру KYC (Know Your Customer) граждане Украины могут пройти несколькими способами:
</p>

<ul>
	<li>
		с помощью заграничного паспорта;
	</li>
	<li>
		через ID-карту (гражданский паспорт).
	</li>
</ul>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/3-verif_step_1_ru-473x1024.jpg.13ce517ceffac2602abd436435d37fe0.jpg" data-fileid="117" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="117" data-ratio="216.76" width="346" alt="3-verif_step_1_ru-473x1024.thumb.jpg.81c8dfef6d2b416799ef73c391a666b3.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/3-verif_step_1_ru-473x1024.thumb.jpg.81c8dfef6d2b416799ef73c391a666b3.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	Далее система просит предоставить электронную почту и подтвердить адрес, пройдя по ссылке с подтверждением.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/4-verif_step_2_ru.jpg.47a704581bd381887b31f404c33530db.jpg" data-fileid="118" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="118" data-ratio="216.76" width="346" alt="4-verif_step_2_ru.thumb.jpg.ee513a3f9035f08b114cd02914c36a3a.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/4-verif_step_2_ru.thumb.jpg.ee513a3f9035f08b114cd02914c36a3a.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	Форма ввода электронной почты. Данные: Trustee Plus.
</p>

<p>
	После предоставления личных данных система попросит указать причины открытия счета в Trustee Plus, а также источник дохода. Из предложенных вариантов можно выбрать лишь один.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/5-verif_step_3_ru.jpg.78feeb379bbfc3d6da2ca46761c49be2.jpg" data-fileid="119" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="119" data-ratio="216.76" width="346" alt="5-verif_step_3_ru.thumb.jpg.feb8fa3fe44bca1d266fa044384c8a77.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/5-verif_step_3_ru.thumb.jpg.feb8fa3fe44bca1d266fa044384c8a77.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/6-verif_step_4_ru.jpg.db3010f02d89bc1f5cb3e151094b6ce1.jpg" data-fileid="120" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="120" data-ratio="216.76" width="346" alt="6-verif_step_4_ru.thumb.jpg.f1041c75d2028a7637d48125bc2d8449.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/6-verif_step_4_ru.thumb.jpg.f1041c75d2028a7637d48125bc2d8449.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	Экран опросника. Данные: Trustee Plus.
</p>

<p>
	Только после прохождения опросника, система берет документы в обработку. В нашем случае письмо с оповещением об успешной верификации пришло в течение всего 10 минут.
</p>

<p>
	Теперь можем внимательно изучить возможности приложения.
</p>

<p>
	<strong>Покупка, обмен и переводы криптовалют</strong>
</p>

<p>
	Trustee Plus работает как криптовалютный кошелек с расширенными возможностями:
</p>

<ul>
	<li>
		поддерживает более 30 токенов и 70 000 торговых пар с разными валютами;
	</li>
	<li>
		работает в сетях Ethereum, Tron, BNB Chain и других блокчейнах;
	</li>
	<li>
		безопасность обеспечивают децентрализованные протоколы с многоуровневой системой защиты;
	</li>
	<li>
		предоставляет сервис для свопа токенов;
	</li>
	<li>
		позволяет выводить активы на банковскую карту и расплачиваться криптовалютами в торговых точках.
	</li>
</ul>

<p>
	Кроме того, в Trustee Plus можно переводить активы по номеру телефона.
</p>

<p>
	Интерфейс приложения выглядит просто и лаконично, а навигация интуитивно понятна пользователю любого уровня. Trustee Plus работает на украинском, русском и английском языках.
</p>

<p>
	В верхнем левом углу отображается иконка личного аккаунта, справа вверху ― оповещения и чат с круглосуточной службой поддержки. Внизу размещаются четыре вкладки: «Кошелек», «Рынок», «Карта» и «Реф» (реферальная программа). Баланс кошелька отображается в центре экрана, однако можно включить режим инкогнито и тогда приложение скроет количество активов на счету.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/7-main_ru.jpg.57f161be5c302a1c177a6ca9279a7542.jpg" data-fileid="121" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="121" data-ratio="216.76" width="346" alt="7-main_ru.thumb.jpg.85dbef4b86526e631d98cfbb2e0379c1.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/7-main_ru.thumb.jpg.85dbef4b86526e631d98cfbb2e0379c1.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/8-support_ru.jpg.4ef91160d8548dff43cfa0c014afa632.jpg" data-fileid="122" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="122" data-ratio="216.76" width="346" alt="8-support_ru.thumb.jpg.1c3c61bedc6ef0e7717da09f6f84010a.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/8-support_ru.thumb.jpg.1c3c61bedc6ef0e7717da09f6f84010a.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	Слева направо: экраны «Кошелек» и интерфейс службы поддержки. Данные: Trustee Plus.
</p>

<p>
	Для работы с приложением прежде всего протестируем переводы криптовалют. Чтобы пополнить баланс выбираем нужный нам актив из предложенного списка (в данном случае USDT). Выбираем опцию «Пополнить по адресу», определяемся в какой сети необходимо сделать перевод (редакция воспользовалась Tron), копируем адрес депозита и начисляем на него средства.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/9-top_up_step_1_ru.jpg.6c81f5e24b2cf80028a90d3843b46f61.jpg" data-fileid="123" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="123" data-ratio="216.76" width="346" alt="9-top_up_step_1_ru.thumb.jpg.c0931262b9b45600e004fb44b7675b8e.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/9-top_up_step_1_ru.thumb.jpg.c0931262b9b45600e004fb44b7675b8e.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/10-top_up_step_2_ru.jpg.f05222d05fad76e603b0771f7dbd4875.jpg" data-fileid="124" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="124" data-ratio="216.76" width="346" alt="10-top_up_step_2_ru.thumb.jpg.700748ce007179263b614a2e975ace3e.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/10-top_up_step_2_ru.thumb.jpg.700748ce007179263b614a2e975ace3e.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	Слева направо: экраны выбора вида перевода и сети. Данные: Trustee Plus.
</p>

<p>
	Система предупреждает, что транзакции объемом менее 5 USDT не будут зачислены на баланс пользователя.
</p>

<p style="text-align:center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="125" data-ratio="37.23" width="591" alt="11-top_up_step_3_ru.jpg.89d0632c8ea0cee25c9cd9e8fbf92361.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/11-top_up_step_3_ru.jpg.89d0632c8ea0cee25c9cd9e8fbf92361.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p style="text-align:center;">
	<em>Предупреждение о минимальной сумме депозита. Данные: Trustee Plus.</em>
</p>

<p>
	<strong>Trustee Plus не взимает комиссии за переводы криптовалют.</strong> Однако блокчейн, с которого мы осуществляли транзакцию, удержал определенное количество TRX в качестве платы за газ.
</p>

<p>
	Как только на наш счет приходят стейблкоины, переходим в меню «Обмен» и конвертируем USDT в криптовалюту Aptos (APT).
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/12-swap_ru.jpg.b8673afcab72c9fbca6068f42f29ed7b.jpg" data-fileid="126" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="126" data-ratio="216.76" width="346" alt="12-swap_ru.thumb.jpg.000f9ee13cb46342e651896c456c8626.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/12-swap_ru.thumb.jpg.000f9ee13cb46342e651896c456c8626.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Экран «Обмен». Данные: Trustee Plus.</em>
</p>

<p>
	Приложение автоматически проводит перерасчет и указывает актуальный курс свопа. <strong>При обмене цифровых активов Trustee Plus удерживает 0,5% комиссии.</strong> Конвертация происходит мгновенно.
</p>

<p>
	<strong>Мониторинг рынка</strong>
</p>

<p>
	Trustee Plus позволяет наблюдать за рыночными настроениями и движениями. В приложении есть вкладка «Топ роста» и «Топ падения». Здесь отображаются наиболее волатильные активы за последние 24 часа.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/13-market_1_ru.jpg.f8ede49a06a6c152f9259c27d2d82f5c.jpg" data-fileid="127" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="127" data-ratio="216.76" width="346" alt="13-market_1_ru.thumb.jpg.c0f3e6272c4f3b8bb72f19ecfcf63d30.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/13-market_1_ru.thumb.jpg.c0f3e6272c4f3b8bb72f19ecfcf63d30.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/14-market_2_ru.jpg.4abfabb0e9d3072ad395cad5b9dfb16a.jpg" data-fileid="128" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="128" data-ratio="216.76" width="346" alt="14-market_2_ru.thumb.jpg.a460a8901d10da60346c6eb5257a6079.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/14-market_2_ru.thumb.jpg.a460a8901d10da60346c6eb5257a6079.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Скриншоты. Данные: Trustee Plus.</em>
</p>

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

<ul>
	<li>
		показатель объема торгов;
	</li>
	<li>
		ценовые максимум и минимум за сутки;
	</li>
	<li>
		общее предложение;
	</li>
	<li>
		максимальное предложение;
	</li>
	<li>
		количество токенов в обращении;
	</li>
	<li>
		исторические ценовые максимум и минимум;
	</li>
	<li>
		короткая справка о токене.
	</li>
</ul>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/15-market_3_ru.jpg.db48191a5288e528ff8e8d56ca0fce59.jpg" data-fileid="129" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="129" data-ratio="216.76" width="346" alt="15-market_3_ru.thumb.jpg.d17630e9c65fddeea00385d954aa2b05.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/15-market_3_ru.thumb.jpg.d17630e9c65fddeea00385d954aa2b05.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/16-market_4_ru.jpg.643841691ad028f4658d5fe6619e2009.jpg" data-fileid="130" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="130" data-ratio="216.76" width="346" alt="16-market_4_ru.thumb.jpg.a39f5198a4303902938e46725cf80d0e.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/16-market_4_ru.thumb.jpg.a39f5198a4303902938e46725cf80d0e.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Страница биткоина в приложении Trustee Plus. Данные: Trustee Plus.</em>
</p>

<p>
	Для каждого актива можно установить персональные настройки, а также поставить оповещения об изменении цен.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/17-market_5_ru.jpg.77629e0a2bdce4f3a19bba35b56b8a71.jpg" data-fileid="131" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="131" data-ratio="216.76" width="346" alt="17-market_5_ru.thumb.jpg.cdfaec309593e1651efc96df5d9ced7c.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/17-market_5_ru.thumb.jpg.cdfaec309593e1651efc96df5d9ced7c.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Настройка уведомлений о движении котировок биткоина. Данные: Trustee Plus.</em>
</p>

<p>
	<strong>Криптовалютная карта и ее возможности</strong>
</p>

<p>
	Главная особенность Trustee Plus ― это наличие виртуальной карты от платежной системы MasterCard. Ее можно привязать к Apple Pay и Google Pay, чтобы оплачивать покупки криптовалютами. Выпуск карты стоит €10.
</p>

<p>
	Для ее открытия нужно пройти верификацию в приложении (о процедуре KYC мы писали выше).
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/18-card_step_1_ru.jpg.8bc7ed40111d340b28199ceafa608d20.jpg" data-fileid="132" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="132" data-ratio="216.76" width="346" alt="18-card_step_1_ru.thumb.jpg.b985d6bf1e87a4d21faa87aa0ab67858.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/18-card_step_1_ru.thumb.jpg.b985d6bf1e87a4d21faa87aa0ab67858.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/19-card_step_2_ru.jpg.cd9c210b16d2078de03bb2554031b12c.jpg" data-fileid="133" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="133" data-ratio="216.76" width="346" alt="19-card_step_2_ru.thumb.jpg.4774238dddc4befdf8057dd6b4927544.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/19-card_step_2_ru.thumb.jpg.4774238dddc4befdf8057dd6b4927544.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/card-issue-trustee-3.jpeg.bc4127c595a02b454e83a3ec2f05aa2a.jpeg" data-fileid="134" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="134" data-ratio="216.76" width="346" alt="card-issue-trustee-3.thumb.jpeg.bd94b80b1cb752cccf38c23f6c2df6d1.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/card-issue-trustee-3.thumb.jpeg.bd94b80b1cb752cccf38c23f6c2df6d1.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Выпуск криптовалютной карты Trustee Plus. Данные: Trustee Plus.</em>
</p>

<p>
	По умолчанию баланс карты отображается в евровом эквиваленте. При нехватке фиатных средств приложение автоматически будет конвертировать цифровые активы.
</p>

<p>
	Далее подключаем к карте криптовалюты. На момент подготовки материала доступны биткоин, Ethereum и USDT. Поскольку ранее мы тестировали переводы, то на нашем счету есть немного стейблкоинов от Tether. 
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/21-card_step_4_ru.jpg.76264b6fadb7f16103e959d2c37416e8.jpg" data-fileid="135" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="135" data-ratio="216.76" width="346" alt="21-card_step_4_ru.thumb.jpg.ac448a0282183e2aeb598084e5a003cb.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/21-card_step_4_ru.thumb.jpg.ac448a0282183e2aeb598084e5a003cb.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Подключение USDT к карте. Данные: Trustee Plus.</em>
</p>

<p>
	<strong>Далее расскажем, как привязать криптокарту Trustee Plus к Apple Pay.</strong>
</p>

<p>
	Сначала открываем приложение Wallet и нажимаем на «+». После выбираем опцию «Дебетовая или кредитная карта» и нажимаем «Продолжить». Вводим данные карты вручную. Выбираем проверку карты через SMS-код, который должен прийти пользователю в приложении Trustee.
</p>

<p style="text-align:center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="136" data-ratio="24.76" width="828" alt="connect-trustee-to-apple-pay.jpeg.3961fc30397dcdb46954a085371e2bc8.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/connect-trustee-to-apple-pay.jpeg.3961fc30397dcdb46954a085371e2bc8.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p style="text-align:center;">
	<em>Добавление виртуальной карты Trustee в Wallet. Данные: Wallet.</em>
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/22_wallet_ru.jpeg.2ff39ab01faba3c2325790be7191bcb3.jpeg" data-fileid="137" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="137" data-ratio="133.45" width="562" alt="22_wallet_ru.thumb.jpeg.1f11370eca11739b440c30705c677863.jpeg" data-src="https://phoenix.lol/uploads/monthly_2024_08/22_wallet_ru.thumb.jpeg.1f11370eca11739b440c30705c677863.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Добавление виртуальной карты Trustee в Wallet. Данные: Wallet.</em>
</p>

<p>
	В нашем случае код-подтверждение не приходил достаточно долго, чтобы мы обратились за помощью в службу поддержки. В чате отреагировали быстро, а проблема решилась в течении двух минут.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/23_support_dialog_ru.png.f5af4c15f432e2664168436c13153c0f.png" data-fileid="138" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="138" data-ratio="216.76" width="346" alt="23_support_dialog_ru.thumb.png.0f84b2fc6e847383c5210f17a351f87b.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/23_support_dialog_ru.thumb.png.0f84b2fc6e847383c5210f17a351f87b.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Чат со службой поддержки Trustee. Данные: Trustee Plus.</em>
</p>

<p>
	<strong>Реферальная программа для сообщества</strong>
</p>

<p>
	Для участия в программе нужно быть верифицированным пользователем приложения и сгенирировать персональную реферальную ссылку, которую можно будет разослать друзьям и знакомым.
</p>

<p>
	Участник сообщества может заработать до 25% дохода Trustee с каждого приглашенного в рамках программы пользователя. Более того, он получает 20% от комиссии за транзакции с пользователей, которые пришли по реферальной ссылке друга.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/referals-program-trustee.png.4567a77bd1aacc0e62f626f51626f8d3.png" data-fileid="139" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="139" data-ratio="79.70" width="941" alt="referals-program-trustee.thumb.png.79b8b5c698820ea60a7ce78067a8f2e6.png" data-src="https://phoenix.lol/uploads/monthly_2024_08/referals-program-trustee.thumb.png.79b8b5c698820ea60a7ce78067a8f2e6.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<span style="background-color:#ffffff;color:#7a7c82;font-size:14px;">Данные:<span> </span></span><a href="https://trusteeglobal.com/ru/referalnaya-programma-trustee-plus/" style="background-color:#ffffff;color:#1d1d1f;font-size:14px;" rel="external nofollow">Trustee Plus</a><span style="background-color:#ffffff;color:#7a7c82;font-size:14px;">.</span>
</p>

<p>
	По словам представителей команды, в программе лояльности участвуют все криптовалюты.
</p>

<p>
	<em>«Интересный факт заключается в том, что 31% всех загрузок осуществлено по рекомендации друзей. Фактически, каждый третий наш пользователь — это результат деятельности комьюнити, которым мы гордимся и которому отдаем дань уважения», — отметил CEO Trustee Вадим Груша.</em>
</p>

<p>
	Помимо реферальной программы разработчики предлагают пользователям зарабатывать награды. Принцип работы весьма прост: чем больше различных операций проводится в приложении, тем больше наград открывается.
</p>

<p>
	За полученные значки пользователю начисляются бонусные гривны в размере от 10 до 30. Однако потратить их можно только на благотворительность в пользу украинской армии, медиков или восстановления страны.
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/24-donat_step_1_ru.jpg.9abaf3e093aee20ac39a7a734f285e0e.jpg" data-fileid="140" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="140" data-ratio="216.76" width="346" alt="24-donat_step_1_ru.thumb.jpg.46856395e0ffd870970f7578e494252b.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/24-donat_step_1_ru.thumb.jpg.46856395e0ffd870970f7578e494252b.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a> <a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_08/25-donat_step_2_ru.jpg.c2d14bf054006856e9554fd4493d0c0b.jpg" data-fileid="141" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="141" data-ratio="216.76" width="346" alt="25-donat_step_2_ru.thumb.jpg.22e811ca4fdb674a0c1322a610f73798.jpg" data-src="https://phoenix.lol/uploads/monthly_2024_08/25-donat_step_2_ru.thumb.jpg.22e811ca4fdb674a0c1322a610f73798.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	<em>Экран «Награды». Данные: Trustee Plus.</em>
</p>

<p>
	<strong>Выводы</strong>
</p>

<p>
	Trustee Plus предлагает клиентам расширенные возможности по управлению активами. Вывод цифровых активов на банковскую карту делает продукт одним из лидеров сегмента.
</p>

<p>
	Множество торговых пар, работа с различными сетями, поддержка NFT, мгновенные интегрированные свопы и простой интерфейс приложения повышают привлекательность продукта.
</p>

<p>
	Кроме того, Trustee Plus можно назвать примером социально ответственного бизнеса. Во время российского вторжения в Украину команда внедряет инструменты поощрения и донатов для сообщества. Полученные средства передаются на благотворительность.
</p>

<p>
	 
</p>

<p style="text-align:center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://trusteeglobal.com/ru/?r=fbx5UMZvdGb" rel="external nofollow"><img alt="Получить карту Trustee Plus" class="ipsImage ipsImage_thumbnailed" data-fileid="112" data-ratio="11.80" style="width:1000px;height:auto;" width="1000" data-src="https://phoenix.lol/uploads/monthly_2024_08/---.thumb.png.30b73c1754dfeb505d69f6b8299eee32.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p style="text-align:center;">
	 
</p>
]]></description><guid isPermaLink="false">13</guid><pubDate>Tue, 13 Aug 2024 21:17:31 +0000</pubDate></item><item><title>Google Search Achievements 600</title><link>https://phoenix.lol/index.php?/blogs/entry/12-google-search-achievements-600/</link><description><![CDATA[<p>
	New small achievement 600
</p>

<p>
	It didn't take long before we got a new achievement. We won't stop! After all, our goal is 20,000
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2024_07/Google-Search-600.png.0b0df70c8bd90d650ca4aedcb1fee53e.png" data-fileid="92" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="92" data-ratio="111.94" width="670" alt="Google-Search-600.thumb.png.0ba541599e00bd06ae700d202c41a81d.png" data-src="https://phoenix.lol/uploads/monthly_2024_07/Google-Search-600.thumb.png.0ba541599e00bd06ae700d202c41a81d.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>
]]></description><guid isPermaLink="false">12</guid><pubDate>Sat, 13 Jul 2024 08:19:47 +0000</pubDate></item><item><title>Google Search Achievements</title><link>https://phoenix.lol/index.php?/blogs/entry/11-google-search-achievements/</link><description><![CDATA[<p>
	Decided to publish the results for chronology in Google Search Achievements
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="91" href="https://phoenix.lol/uploads/monthly_2024_07/Phoenix.lol-500-Google_Search.png.aeee7e2882e0b6d1ec90b905e4c7ce44.png" rel=""><img alt="Phoenix.lol-500-Google_Search.thumb.png.ef3c82ea709835554992f8336cc8b7a2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="91" data-ratio="111.77" style="height:auto;" width="671" data-src="https://phoenix.lol/uploads/monthly_2024_07/Phoenix.lol-500-Google_Search.thumb.png.ef3c82ea709835554992f8336cc8b7a2.png" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">11</guid><pubDate>Sat, 06 Jul 2024 10:25:20 +0000</pubDate></item><item><title>Starlink</title><link>https://phoenix.lol/index.php?/blogs/entry/10-starlink/</link><description><![CDATA[<p>
	<img alt="StarLink.jpeg.0331323c1d943f366968f2c3d95ac526.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="90" data-ratio="100.00" style="height:auto;" width="225" data-src="https://phoenix.lol/uploads/monthly_2024_06/StarLink.jpeg.0331323c1d943f366968f2c3d95ac526.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	I ordered a Starlink plate from Elon Musk <span class="ipsEmoji">🙂</span><br />
	soon this will probably be the first forum and three online stores located on a yacht, and 70% of the time located in open territorial waters!
</p>

<p>
	<a href="https://www.starlink.com/boats" rel="external nofollow">https://www.starlink.com/boats</a>
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">10</guid><pubDate>Wed, 19 Jun 2024 08:16:28 +0000</pubDate></item><item><title>Manually upgrade OpenSSH on OS 10.9.x</title><link>https://phoenix.lol/index.php?/blogs/entry/9-manually-upgrade-openssh-on-os-109x/</link><description><![CDATA[<p>
	<strong><span>Manually upgrade OpenSSH on OS 10.9.x</span></strong>
</p>

<p>
	<span>NOTE: Installation and testing was done on a clean Mavericks (OS 10.9) installation</span>
</p>

<p>
	 
</p>

<p>
	<strong><span>Install Brew:</span></strong>
</p>

<p>
	<span>Install Homebrew prereqs:</span>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">xcode-select --install</span></pre>

<p>
	<strong><span>Install Homebrew</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"</span></pre>

<p>
	<span>Enable Brew to override OSX system binaries</span>
</p>

<p>
	<span>brew tap homebrew/dupes</span>
</p>

<p>
	<span>Upgrade OpenSSL which is required for OpenSSH</span>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">brew install openssl</span></pre>

<p>
	<strong><span>Upgrade OpenSSH</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">brew install openssh --with-brewed-openssl --with-keychain-support</span></pre>

<p>
	<strong><span>Change default ssh-agent used by system</span></strong>
</p>

<p>
	<span>Make a backup of original plist file:</span>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo cp /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist Desktop/</span></pre>

<p>
	<strong><span>Edit the plist file:</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo vim /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist </span></pre>

<p>
	<strong><span>Replace the following two lines:</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="tag">&lt;string&gt;</span><span class="pln">/usr/bin/ssh-agent</span><span class="tag">&lt;/string&gt;</span><span class="pln">

        </span><span class="tag">&lt;string&gt;</span><span class="pln">-l</span><span class="tag">&lt;/string&gt;</span></pre>

<p>
	<strong><span>With this:</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="tag">&lt;string&gt;</span><span class="pln">/usr/local/bin/ssh-agent</span><span class="tag">&lt;/string&gt;</span><span class="pln">

        </span><span class="tag">&lt;string&gt;</span><span class="pln">-D</span><span class="tag">&lt;/string&gt;</span></pre>

<p>
	<span><strong>NOTE the dash before the</strong> D </span><span><b>-D</b></span>
</p>

<p>
	 
</p>

<p>
	<strong><span>Update the system to see the changes to the plist file:</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">launchctl unload /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist 

launchctl load -w /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist 

launchctl start org.openbsd.ssh-agent

launchctl list | grep org.openbsd.ssh</span></pre>

<p>
	<strong><span>Replace the ssh system binary with a symlink to the new Brew'ed ssh binary</span></strong>
</p>

<p>
	<span>Backup the original binary:</span>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo mv /usr/bin/ssh Desktop/</span></pre>

<p>
	<strong><span>Create the symlink:</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo ln -s /usr/local/bin/ssh /usr/bin/ssh</span></pre>

<p>
	<strong><span>Add the following snipped to </span><span>all</span><span> users </span><span>.bash_profile</span><span> file</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">eval $(ssh-agent)

    function cleanup {

        echo \"Killing SSH-Agent\"

        kill -9 $SSH_AGENT_PID

    }

trap cleanup EXIT</span></pre>

<p>
	<strong><span>Reboot the system:</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">sudo shutdown -r now</span></pre>

<p>
	<strong><span>Check that system is using the new SSH version</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">ssh -V</span></pre>

<p>
	<strong><span>Remove homebrew dupes</span></strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">brew untap homebrew/dupes</span></pre>

<p>
	 
</p>
]]></description><guid isPermaLink="false">9</guid><pubDate>Tue, 07 May 2024 05:48:32 +0000</pubDate></item><item><title>Today I added a lot of useful modules for WHMCS.</title><link>https://phoenix.lol/index.php?/blogs/entry/8-today-i-added-a-lot-of-useful-modules-for-whmcs/</link><description><![CDATA[<p style="text-align:center;">
	 
</p>

<p>
	Today I added a lot of useful modules for WHMCS.
</p>

<p>
	All modules do not require licenses!<br />
	You can download it in the section:
</p>

<p>
	<a href="https://phoenix.lol/index.php?/forum/63-whmcs/" rel="">https://phoenix.lol/index.php?/forum/63-whmcs/</a>
</p>
]]></description><guid isPermaLink="false">8</guid><pubDate>Mon, 01 Apr 2024 11:43:57 +0000</pubDate></item><item><title>Invision Community update</title><link>https://phoenix.lol/index.php?/blogs/entry/7-invision-community-update/</link><description><![CDATA[<p>
	Для того чтобы обновить закачайте файлы на сервер перепишите поверх старых и запустите:
</p>

<p>
	<span style="background-color:#ffffff;color:#2f3d4b;font-size:14px;">yoursite.com/admin/upgrade</span>
</p>
]]></description><guid isPermaLink="false">7</guid><pubDate>Mon, 04 Mar 2024 04:45:34 +0000</pubDate></item><item><title>MikroTik SSL certificate</title><link>https://phoenix.lol/index.php?/blogs/entry/6-mikrotik-ssl-certificate/</link><description><![CDATA[<p>
	Letsencrypt сертификат в mikrotik
</p>

<p>
	в 7й версии таки появилась возможность запросить и установить ssl сертификат))))) 
</p>

<p>
	/certificate enable-ssl-certificate dns-name=%domainname%
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">6</guid><pubDate>Wed, 07 Feb 2024 18:09:40 +0000</pubDate></item><item><title>&#x41A;&#x442;&#x43E; &#x442;&#x440;&#x44F;&#x441;&#x451;&#x442; &#x431;&#x430;&#x43D;&#x43A;&#x443;?</title><link>https://phoenix.lol/index.php?/blogs/entry/4-%D0%BA%D1%82%D0%BE-%D1%82%D1%80%D1%8F%D1%81%D1%91%D1%82-%D0%B1%D0%B0%D0%BD%D0%BA%D1%83/</link><description><![CDATA[<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://phoenix.lol/uploads/monthly_2023_12/601813514_.jpeg.60829556f0825fa7795eb0615fd81f08.jpeg" data-fileid="21" data-fileext="jpeg" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="21" data-ratio="100.00" width="750" alt=".thumb.jpeg.233ac60546034f1b0f39318110725005.jpeg" data-src="https://phoenix.lol/uploads/monthly_2023_12/.thumb.jpeg.233ac60546034f1b0f39318110725005.jpeg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<span style="background-color:#ffffff;color:#050505;font-size:15px;">Знаете ли вы, что если поместить в банку 100 черных и 100 красных муравьев, ничего не произойдет? Но если сильно потрясти банку, муравьи начнут убивать друг друга. Красные муравьи считают черных муравьев своими врагами, а черные муравьи считают красных муравьев своими врагами. Настоящий враг тот, кто трясет банку. То же самое происходит и в человеческом обществе. Итак, прежде чем нападать друг на друга, нам следует подумать, кто трясет банку! - Курт Воннегут</span>
</p>
]]></description><guid isPermaLink="false">4</guid><pubDate>Mon, 11 Dec 2023 07:53:57 +0000</pubDate></item><item><title>&#x421;&#x442;&#x438;&#x432;&#x435;&#x43D; &#x41A;&#x438;&#x43D;&#x433;: &#x425;&#x43E;&#x43B;&#x43B;&#x438;</title><link>https://phoenix.lol/index.php?/blogs/entry/3-%D1%81%D1%82%D0%B8%D0%B2%D0%B5%D0%BD-%D0%BA%D0%B8%D0%BD%D0%B3-%D1%85%D0%BE%D0%BB%D0%BB%D0%B8/</link><description><![CDATA[<h1 style="background-color:#ffffff;color:#222222;font-size:24px;text-align:left;">
	Стивен Кинг: Холли
</h1>

<p>
	<img alt="spacer.png" class="ipsImage" data-ratio="75.08" height="750" style="height:auto;" width="491" data-src="https://fastsell.shop/uploads/images/202310/cf04640497-2ae16fcb19-1f36304a28.jpg" src="https://phoenix.lol/applications/core/interface/js/spacer.png" />
</p>

<p>
	 
</p>

<p>
	Отличная новинка для чтения)
</p>

<p>
	Всего за 1 евро.
</p>

<p>
	Рекомендую.
</p>

<p style="background-color:#ffffff;color:#222222;font-size:14px;text-align:left;">
	Когда Пенни Даль звонит в детективное агентство «Найдём и сохраним» в надежде на помощь в поиске пропавшей дочери, Холли не хочет браться за дело. У её партнера Пита ковид, а мать только что умерла, и Холли как никогда нуждается в отпуске. Но что-то в отчаянном голосе Пенни Даль не позволяет Холли отказать ей.
</p>

<p style="background-color:#ffffff;color:#222222;font-size:14px;text-align:left;">
	В нескольких кварталах от того места, где пропала Бонни Даль, живут профессора Родни и Эмили Харрис. Они представляют собой образец буржуазной респектабельности: женатые восьмидесятилетние, преданные друг другу пенсионеры, всю жизнь занимающиеся наукой. Но они скрывают грязную тайну в своём ухоженном, заставленном книгами доме и это может быть связано с исчезновением Бонни.
</p>

<p style="background-color:#ffffff;color:#222222;font-size:14px;text-align:left;">
	Почти невозможно понять, что замышляют Харрисы: они сообразительны, терпеливы и безжалостны. Холли должна задействовать все свои таланты, чтобы перехитрить эту изворотливую пару профессоров.
</p>

<p style="background-color:#ffffff;color:#222222;font-size:14px;text-align:left;">
	<a href="https://fastsell.shop/king-stiven-kholli-359925" rel="external nofollow">Купить "Стивен Кинг: Холли"</a> за 1 евро или по курсу...
</p>

<p style="background-color:#ffffff;color:#222222;font-size:14px;text-align:left;">
	 
</p>
]]></description><guid isPermaLink="false">3</guid><pubDate>Sun, 19 Nov 2023 14:48:46 +0000</pubDate></item><item><title>&#x41E;&#x447;&#x435;&#x43D;&#x44C; &#x43A;&#x43B;&#x430;&#x441;&#x441;&#x43D;&#x44B;&#x435; &#x43B;&#x43E;&#x430;&#x434;&#x435;&#x440;&#x44B; css</title><link>https://phoenix.lol/index.php?/blogs/entry/2-%D0%BE%D1%87%D0%B5%D0%BD%D1%8C-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BD%D1%8B%D0%B5-%D0%BB%D0%BE%D0%B0%D0%B4%D0%B5%D1%80%D1%8B-css/</link><description><![CDATA[<p>
	<a href="https://cssloaders.github.io/" rel="external nofollow">https://cssloaders.github.io/</a>
</p>
]]></description><guid isPermaLink="false">2</guid><pubDate>Wed, 25 Oct 2023 19:33:14 +0000</pubDate></item></channel></rss>
