Записване на набори от данни в споделена памет с PHP

Ръководство стъпка по стъпка за използване на PHP споделена памет като място за съхранение

Споделената памет е ефективен начин за споделяне на данни между приложения на една и съща машина. Един процес създава споделен сегмент от паметта, до който други процеси имат достъп, ако имат правилните разрешения. Всеки сегмент получава уникален shmid идентификатор, който определя областта на физическата памет, където други процеси могат да работят с него. Веднъж създаден, сегментът става достъпен за други процеси на същата машина, които имат съответните разрешения и могат да извършват операции за четене, запис и изтриване.

Това означава, че приложение, написано на C, може да комуникира с приложение, написано на друг език като Java™ или PHP. Те могат да обменят информация само ако са в състояние да приемат и разбират тази информация. Споделената памет се използва широко в реализациите, налични за повечето езици, така че получаването на достъп не би трябвало да е проблем. Що се отнася до разбирането на информацията, може да се използва стандартен формат като XML или JSON.

Споделената памет е бърз начин за обмен на данни между процесите, главно защото след като сегментите са създадени, ядрото на операционната система не взема никакво участие в процеса на прехвърляне на данни. Такива техники често се наричат ​​"междупроцесна комуникация" (IPC). Други IPC методи включват тръбопроводи, опашки от съобщения, RPC и сокети. Този бърз и надежден начин за споделяне на данни между приложения е безценен, когато се работи с екосистема от приложения, които трябва да комуникират помежду си. Обичайният метод за използване на бази данни за споделяне на информация между приложения често води до бавна обработказаявки и дори блокиране на I/O, в зависимост от размера на екосистемата. Когато работите със споделена памет, няма I/O операции, които забавят процеса.

Тази статия предоставя лесен начин за създаване и използване на сегменти от споделена памет с помощта на PHP за съхраняване на набори от данни, които други приложения могат да използват. Дори и да нямате план за използване на споделена памет за комуникация, можете да се възползвате, защото приложенията не трябва да се справят с I/O проблеми. Съхраняването на набори от данни директно в паметта има много предимства, от кеширане на данни от уеб услуги до споделяне на сесии. Това е много полезна концепция, с която всеки PHP разработчик трябва да е запознат.

Споделена памет и PHP

PHP има широк набор от разширения, включително такива за работа със споделена памет. Но разработчиците могат лесно да манипулират сегменти с няколко общи функции, без да инсталират никакви разширения.

Създаване на сегменти

Функциите за споделена памет са подобни на функциите за управление на файлове, само че вместо нишки работите с идентификатори за достъп до споделена памет. Първият пример е функцията shmop_open, която ви позволява да отворите съществуващ или да създадете нов сегмент. Тази функция е много подобна на класическата функция fopen, която отваря потоци за манипулиране на файлове, връщайки ресурс, наличен за използване от други функции, които четат или записват в този отворен поток. Помислете за функцията shmop_open, показана в списък 1.

Листинг 1. Функция shmop_open

Първият параметър е ID на системата. Това е число, което определя сегмент от споделена памет в системата. Вторият параметър е режимът на достъп, който е много подобен на режима на достъп на функцията fopen. Сегментът може да бъде достъпен с четириначини:

  • режим "a" ви позволява да получите достъп до сегмента само за четене;
  • режим "w" позволява достъп до сегмента за четене и писане;
  • в режим "c" се създава нов сегмент, а ако вече съществува, се прави опит за отварянето му за четене и запис;
  • режим "n" създава нов сегмент и ако вече съществува, се издава съобщение за грешка.

Третият параметър са разрешенията за сегмента. Тук трябва да въведете осмично число.

Четвъртият параметър определя размера на сегмента в байтове. Преди да запишете данни в сегмент, е необходимо да разпределите необходимия брой байтове в него.

Имайте предвид, че тази функция връща идентификационен номер, който може да се използва с други функции за манипулиране на сегмента на споделената памет. Това е идентификатор за достъп до споделена памет, различен от системния идентификатор, подаден като параметър. Не ги бъркайте. При повреда функцията shmop_open ще върне FALSE.

Пишете на сегменти

За да запишете данни в блок споделена памет, използвайте функцията shmop_write. Той е много лесен за използване и приема само три параметъра. Вижте списък 2.

Листинг 2. Използване на shmop_write за запис в блок споделена памет

Подобно е на функцията fwrite, която приема два параметъра: ресурсът на отворения поток, върнат от fopen, и данните, които трябва да бъдат записани. Функцията shmop_write прави същото.

Четене от сегменти

Четенето от споделени сегменти на паметта е проста процедура. Достатъчно е да отворите сегмента и да използвате функцията shmop_read. Приема няколко параметъра и работи подобно на функцията fread. Листинг 3 показва пример за четене на съдържанието на файл в PHP.

Листинг 3. Използване на функциятаshmop_read за четене на съдържанието на файл

Четенето на съдържанието на сегмент от споделена памет се извършва по същия начин, както е показано в списък 4.

Листинг 4. Четене на съдържанието на сегмент от споделена памет

Обърнете внимание на параметрите. Функцията shmop_read приема идентификатора, върнат от функцията shmop_open, с която вече сме запознати, и два други параметъра. Вторият параметър е местоположението, от което да започне четенето на сегмента; и третото е броят байтове за четене. Вторият параметър винаги може да бъде 0, началото на данните, но третият може да причини проблем, тъй като може да не знаем колко байта искаме да прочетем.

Това е много подобно на поведението на функцията fread, която приема два параметъра: отворения ресурс на потока, върнат от fopen, и броя байтове за четене от този поток. За да прочетете целия файл, използвайте функцията filesize, която връща броя байтове във файла.

За щастие, когато работите със сегменти от споделена памет, функцията shmop_size, подобно на функцията filesize, връща размера на сегмента в байтове. (Вижте списък 5).

Листинг 5. shmop_size връща размера на сегмента в байтове

Изтриване на сегмент

Ние знаем как да отваряме, пишем и четем споделени сегменти от паметта. За да завършим нашия CRUD клас, всичко, което остава, е да научим как да изтриваме сегменти. Тази задача може лесно да бъде решена с функцията shmop_delete, която се нуждае само от един параметър: ID на сегмента от споделена памет, който искаме да изтрием.

Листинг 6. Функцията shmop_delete маркира сегмент за изтриване

Всъщност не изтрива сегмента. Той го маркира за изтриване, тъй като сегментът на споделената памет не може да бъде изтрит, докато има други процеси, които го използват. функцияshmop_delete маркира сегмента за изтриване и не позволява на друг процес да го отвори. Сега, за да изтриете сегмент, той трябва да бъде затворен.

Затваряне на сегмента

Когато отворите сегмент от споделена памет, вие се "прикрепяте" към него. Веднъж прикрепен към сегмент, можете да записвате данни в него и да четете данни от него, но когато работата приключи, трябва да се откачите от сегмента. Това се прави с помощта на функцията shmop_close, както е показано в списък 7.

Тя е много подобна на функцията fclose при работа с файлове. След отваряне на поток с файл и четене или запис в него, този поток трябва да бъде затворен, в противен случай ще настъпи блокиране.

Листинг 7. Използване на shmop_close за отделяне от сегмент

Използване на споделена памет като място за съхранение

С основни познания за споделена памет и основни CRUD операции върху сегменти от споделена памет можете да започнете да прилагате тези знания на практика. Споделената памет може да се използва като уникална алтернатива за съхранение, която предлага предимства като бързи операции за четене/запис и комуникация на процеса. За уеб приложение това означава:

  • буферна памет (съхранение на заявки към базата данни, данни за уеб услуги, външни данни);
  • памет за сесии;
  • обмен на данни между приложенията.

Преди да продължа, бих искал да представя малка библиотека SimpleSHM. Това е компактен абстракционен слой за работа със споделена памет в PHP, който ви позволява лесно да манипулирате сегменти, като използвате обектно-ориентиран подход. Тази библиотека ви помага да пишете много по-чист код, когато пишете малки приложения, които използват споделена памет за съхраняване на данни. За да започнете с SimpleSHM, изтеглете tarball файла от страницатаGitHub.

Има три вида операции: четене, запис и изтриване. Простото инстанциране на обект от класа ще осигури споделен сегмент от паметта. Акцентите са показани в листинг 8.

Листинг 8. Основи на SimpleSHM

Имайте предвид, че ID не се предава на класа. Тъй като идентификаторът не се предава, номерът ще бъде избран на случаен принцип и ще се отвори нов сегмент с този номер. Можете да предадете число като параметър на конструктора, за да отворите сегмента или да го създадете със специфична ID стойност, както е показано в списък 9.

Листинг 9. Отваряне на даден сегмент

Магическият метод __destructor се грижи за извикването на shmop_close на сегмент, за да деактивира обекта и да го отдели от сегмента. Нека го наречем "SimpleSHM 101". Сега нека го използваме за по-висока цел: използване на споделена памет като място за съхранение. Сериализацията е необходима за съхраняване на набори от данни, тъй като масивите или обектите не могат да се съхраняват в паметта. Тук JSON се използва за сериализиране, но всеки друг метод ще работи, като XML или вградените функции за сериализиране на PHP. Пример е показан в списък 10.

Листинг 10. Използване на споделена памет като място за съхранение

Успешно преобразувахме масива в JSON низ, съхранихме го в споделен блок памет, прочетохме го, преобразувахме JSON низа обратно в масив и го показахме. Всичко изглежда тривиално, но само си представете какви възможности отваря този фрагмент. Може да се използва за съхраняване на резултатите от заявки за уеб услуги, бази данни или дори като процесорен буфер за текстови шаблони. Записването и четенето от паметта ще осигури много по-добра производителност от записването и четенето от диск.

Този метод на съхранение е полезенсамо за използване като буфер, но също и за обмен на данни между приложения, ако тези данни се съхраняват във формат, разбираем и за двете приложения. Не подценявайте силата на споделената памет в уеб приложенията. Има много различни начини за ефективно внедряване на такова съхранение и единственото ограничение тук са талантът и уменията на програмиста.

Заключение

Какво следва?

Идентифицирахме някои често срещани задачи, за които споделената памет е идеална, като кеширане, споделяне на сесии и комуникация между приложения. Това въведение в споделената памет позволява на читателя да изследва много по-елегантни решения на общи проблеми. Чувствайте се свободни да разширите текущото внедряване на SimpleSHM, за да отговаря на вашите нужди и да направите тези промени в проекта.

Изтегляне на ресурси

Свързани теми

  • Оригинална статия: Съхранявайте набори от данни директно в споделена памет с PHP.
  • Интерфейсът за програмиране на Linux на Michael Kerrisk има отлични глави за комуникацията между процесите, а глави 45-48 са посветени на IPC System V.
  • Статията на Дейв Маршал IPC: Споделена памет описва интересен и прагматичен подход към функциите на споделената памет в C.
  • Книгата на Ричард Стивънс Програмиране на UNIX мрежа съдържа отлични технически материали и описание на няколко реализации на езика C. Вижте откъс от глава в тази книга.
  • Следвайте developerWorks в Twitter.

Коментари