All streams
Search
Write a publication
Pull to refresh
6
0
Евгений Кольцов @mail-online

Пользователь

Send message
О боже, lair… Если вы способны забить своим оборудованием датацентр… я думаю вы просто свой датацентр сделаете, 2 датацентра, 3, 4…

Хранение файлов это «одно из»…
Виртуалки затем чтобы не делать двойную работу. В данном примере с облаком — это резервный вариант. У вас поменялась структура и что, вам вместо того чтобы сделать копию надо менять структуру в облаке на аналогичную… это путь в никуда. Резервный вариант должен делаться копией, а не силами разработчиков переписываться.
Вообще как сказал один мой знакомый сисадмин: «виртуализация, это наше все».
… а когда и этого «отдельного оборудования» перестанет хватать?


Тогда буду решать вопрос в индивидуальном порядке
1) Причем тут оператор. Этот закон ко всем относится. Если у вас на сайте регистрируется пользователь и он может оставлять какие-то свои персональные данные или данные по своим клиентам, все, только РФ.
У меня все в комплексе, в том числе файлы. Глупо хранить именно файлы за рубежом отдельно от всего остального…

Слушал недавно по бфм интервью кого-то из битрикса (не помню уже кто), по этому поводу. У них все на амазоне было и весьма непросто было переехать в РФ. Издержки сейчас выросли на треть вроде из-за этого.

У операторов по Яровой голова болит…

2) А что вас в данном случае смущает? Покупайте оборудование и ставьте дальше в датацентре.

3) Нельзя в облаке делать виртуалки внутри виртуальных машин. Проксмокс например требует от процессора поддержки аппаратной виртуализации, это у хостеров не поддерживается. Т.е. грубо говоря беря в облаке виртуальный сервер, вы не сможете на нем поставить гипервизор и внутри него сделать виртуалки.
А строить все в облаке с нуля вместо того чтобы скопировать структуру, на мой взгляд это просто мартышкин труд, тем более что это надо сделать просто на всякий случай.
Такое сложно представить в SaaS концепции. Но если вдруг будет такой совсем «жирный» клиент. Я ему просто выделю отдельное оборудование. Но вообще обычно в этом случае «коробочные версии» делают.
По этому вопросу еще озвучу свои мысли.

Компрессия/декомпрессия файлов не относится к общему случаю.
Объём диска обычно дешевле процессорного времени, если вы не файл/фото хостинг
Поэтому сжимать изначально — нет смысла, поскольку это относится к оптимизации.


Изначально файл грузится в оригинальном виде. Потом в фоновом режиме проверяется имеет ли смысл вообще его трогать. Для проверки и сжатия можно выделить виртуалку с одним ядром (ограничим влияние на остальные ресурсы), тут нам не важно чтобы все летало, т.к. работа в фоне. Если его можно сжать неплохо то имеет, если сжатие кпеечное, то конечно нет.
И сжимать только маленькие файлы, извлечение которых процесс очень быстрый и не заметен для пользователя.
В общем на мой взгляд тут должен быть вопрос целесообразности. Как показывает практика, в процессе работы офиса в основном прикладывается куча небольших файлов (xls, doc, pdf) они неплохо сжимаются, имеют небольшой объем и их отдача из сжатого вида получается весьма быстрой.
Посмотрим конечно что будет еще при возрастании объемов, если что данный механизм всегда можно отключить и далее хранить в оригинальном виде все.
Спасибо за ссылку. Действительно все вместе и по полочкам. Много интересного.

Да, хранить все в одной БД — проще.
Это пока единственный аргумент «за».
Но для случаев, когда «проще» имеет смысл — о масштабировании проще забыть.
Или то, или другое.


У меня не в одной БД. Структура такая, каждой компании выделяются аккаунт, каждый сотрудник компании может войти в этот аккаунт (со своими правами конечно). Каждому аккаунту выделяется своя рабочая база данных, файловая база данных, база данных для хранения логов и т.д. Есть база данных со структурой, где хранится у какой компании какая БД и на каком сервере она находится. При авторизации пользователя из базы данных со структурой получаем адресацию хранения его БД, и после он работает уже только с ними.
На серверах с БД есть скрипты и исходник БД с типовой конфигурацией. При регистрации происходит копирование типовой БД и запись в базу структуры ее адреса нахождения.
Масштабируемость неограниченная получается.

По бекапам. Рабочую базу все равно надо бекапить. Бекапить заодно и его файловую базу в данном случае не сложно, фактически один механизм. Ничего дополнительно городить не надо.
У меня реализован механизм управления бекапом от пользователя, он сам указывает в какие дни, в какой временной диапазон и какие базы бекапить, за сколько дней хранить копии и т.п. Технически — обновляется cron на нужном сервере в соответствии с планом бекапов. На сервере для бекапов работает скрипт, который просматриает по ftp папочки на этих серверах с определенной периодичностью и тянет к себе файлы, удаляет оригиналы бекапов освобождая место.
Сейчас так нельзя по российскому законодательству. Хранить персональные данные можно только на территории РФ. 152-ФЗ, 242-ФЗ.

Стоимость же аренды виртуалок например на M8 впечатлит любого. За несколько месяцев аренды можно просто купить аналогичные б\у сервера и разместить их в датацентре по цене 2.5-3 тыс в месяц за 1U. Да и неизвестно какие мощности тебе на самом деле выделяют, не факт что как написано, а тут ты знаешь что у тебя есть.

В третьих. Нет поддержки второго уровня виртуализации. Я одно время продумывал вариант аренды со спящими виртуалками на случай физического выхода из строя оборудования, но вот просто взять и свою конфигурацию перенести не получится, нельзя у них сделать виртуалку например с проксмоксом и туда скопировать свою структуру. В общем этот вопрос в итоге решается дополнительным железом, где лежат копии виртуалок, которые можно быстро поднять. Это же железо можно юзать для хранения бекапов, логов и т.д.
Ок, Fortop.

Давайте по полочкам. Рассматриваем мы бесплатную СУБД.
Oracle и MSSQL Server нет. Денег на них нет, а есть только бесплатный Firebird. У стартапов такое бывает весьма часто. Надо при минимуме бабла, выжать максимум производительности.

Решить следующее:

Файлы пользователей должны храниться вне веб сервера. Система должна быть распределенной и неограниченно масштабируемой. Файловых серверов может быть сколько угодно и они могут добавляться в процессе работы. Нужно иметь возможность достаточно просто организовать миграцию файлов клиента на другой сервер при необходимости (например заполнено 70% места, добавили еще сервер, 35% оставить на старом, 35% переместить на новый так чтобы никто ничего не заметил, и дальше равномерно раскидывать новых клиентов по двум серверам. Потом следующий сервер и т.д.).

Файлы аккаунта должны бекапится (отдельный файл архива со всеми файлами). С возможностью передачи архива на оборудование клиенту по графику (если он настроит свой ftp в системе планирования бекапов)

Какие варианты я вижу для решения этой задачи:
а) Samba-server и cifs, класть файлы локально вне каталога веб сервера
б) Загружать их на файловый сервер по ftp
в) Хранить их в базе данных (каждому аккаунту своя база данных с которой он работает)

GridFS я никогда не использовал и возможно мое мнение будет субъективное, но я не вижу никаких преимуществ, так же надо файл туда положить, так же его взять оттуда и произвести над ним операции. Разве что возможно чуть быстрее будет, чем с реляционной БД

Отдача файлов.
1) В любом случае это не прямая ссылка, это скрипт с header. Как минимум соображения безопасности это диктуют.
2) Файл может быть сжатым. На мой взгляд для сжатия лучше использовать стандартные архиваторы (они работают эффективно). Перед отдачей пользователю, его надо разархивировать.
В случаях б) и в) файл надо стащить на веб-сервер чтобы сделать эту операцию.
В случае а) можно сразу архиватором читать файл по сети, а оригинал сохранять на веб сервере.
3) Как отдавать.
Самый простой (но возможно действительно не самый эффективный) вариант — как описан в статье. Делаем нужный header и выводим в скрипт данные файла. После файл стираем.

Возможно вы правильно советуете через nginx, я этого не пробовал, но мне стало интересно, обязательно попробую. Почитал, можно через X-Accel. Он даже может взять их с другого сервера, насколько я понял. В документации сказано что так
location / files {
internal;
proxy_pass http://127.0.0.2;
}


Да, соглашусь, неплохо все. Но как же масштабируемость? А если много серверов откуда надо брать? Т.е. надо скриптом их грузить на этот сервер с которого потом будет отдача и header(«X-Accel-Redirect: /files/». $path);
Вообще предполагаю что можно сделать location / files1{}, location / files2{} и т.д. и в зависимости от того на каком файловом сервере и изымать по нужному пути, но описания этого я сходу не нашел, поэкспериментировать придется.
А вообще именно база данных для хранения файла была выбрана из соображений удобства. Просто бекапить, просто мигрировать на другой сервер, просто накатить новый. Купил железку, накатил проксмокс, сделал копию виртуалки, поменял IP, почистил, прописал ее настройки в базе распределения – все подхватилось и все работает. Так же файловая база в моем случае решает проблему хранения типа данных image в моем внутреннем языке программирования, но это мой индивидуальный случай.

Но вообще, если что подскажите, что решит описанные проблемы и будет удобно в эксплуатации, буду благодарен и обязательно изучу если не знаю. Но пока получилось решить так.
Вы хотите индексы по блобам делать?..
Хранение файла вне веб-сервера, в любом случае оверхед.
а со случайным, какое имя файла будет при загрузке — неизвестно заранее

Почему неизвестно? В таблице files делается поле filename (или filepath). Информация о файле в базе есть, разница в том, что контент файла там не хранится.

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

Только на веб сервер нужно монтировать сетевые диски.

Зачем? Если например использовать FTP, то достаточно вызова ftp_put().

Эта мысль приходила, так конечно можно но… время! ФТП не самый быстрый протокол. Пользователь все это время будет ждать загрузку. Хотя что быстрее: взять файл по фтп или из блоба, вопрос на самом деле открытый.

Как что мешает? А какой файл вы собрались делать exec('7z ...')?

Вызывается скрипт file_b.php?id=123. В нем написано примерно такое:

Да, тут вы правы! Действительно с file_put_contents может получиться. Не приходило в голову. Потестирую, если все ок будет обновлю статью.
TerraV — улыбнуло :)
Но вообще это просто нестандартный подход. Он имеет свои плюсы при использовании в определенных задачах. Просто никто не может на него посмотреть с другой стороны, не как привыкли.
1) Неизвестно имя файла, т.е. ссылкой его дернуть не получится

Если не разрешать доступ к файловому серверу из интернета, то тоже ссылкой его дернуть будет нельзя. Вы же к базе не даете открытый доступ.

Возможно не совсем корректно выразился. Имею ввиду что при загрузке файлы загружается не с тем именем которое было на компьютере заружающего, а со случайным, какое имя файла будет при загрузке — неизвестно заранее. Т.е. ссылкой его дернуть не получится, т.к. имя низвестно.

2) Во вторых можно грузить в каталог ниже каталога веб сервера

Ну так и если хранить в файлах, можно так же грузить. Доступ все равно через скрипт, а не по прямой ссылке.

3) В третьих он грузится на миг, т.е. только на время работы скрипта, скрипт этот файл после загрузки в БД с веб сервера удалит.

Если файлы грузятся на отдельный сервер, то будет точно то же самое.


Да, можно так же грузить. Только на веб сервер нужно монтировать сетевые диски. Ставить самба сервер. Это как варинат да, но на мой взгляд менее удобно. В принципе можно заниматься монтированием и писать пути.

Смотря чем архивирован. Для 7z очень сомневаюсь. Можно только zip насколько я знаю. Это одна из реализаций.

Нет, что мешает вызвать exec('7z ...') в этом же скрипте, без использования CURL?

Как что мешает? А какой файл вы собрались делать exec('7z ...')? Нужно файл добыть сначала. Это делается CURL.
Эти уязвимости есть, если вы загружаете файл на тот же сервер, где работает интерпретатор PHP, и к тому же есть прямой доступ из интернета к загруженным файлам. У вас отдельный сервер для файлов с доступом через скрипт. Так что тут нет разницы, хранить их в базе или на диске. Если я правильно понимаю, из преимуществ остается только удобство бекапа средствами БД.

1) Неизвестно имя файла, т.е. ссылкой его дернуть не получится
2) Во вторых можно грузить в каталог ниже каталога веб сервера
3) В третьих он грузится на миг, т.е. только на время работы скрипта, скрипт этот файл после загрузки в БД с веб сервера удалит.

При извлечении аналогично, он только миг присутствует на веб сервере.

В основной базе в таблице files хранится путь к файлу. В таком варианте ничего городить не надо, запрос идет только в основную БД. После проверки прав содержимое так же отдается через stream. Для удобства переноса можно адрес сервера в отдельном поле хранить.

Примерно так и сделано. Данные в файловой базе — избыточны. Но они удобны для анализа. Конечно можно без них сделать. С ними просто удобнее в случае работы именно с данным файлов, не надо дергать основную базу.

«Все, у нас файл записан в файловое хранилище на другом сервере. На веб-сервере его нет.»
В чем принципиальная разница?

Веб сервер не «резиновый». В него не влезут файлы 1000 клиентов… Масштабируемость нужна. При необходимости покупается новый сервер, его адрес прописывается в настройках и на нем создаются базы новых клиентов и туда все пишется.

Зачем? Что мешает разархивировать в этом же скрипте?

Смотря чем архивирован. Для 7z очень сомневаюсь. Можно только zip насколько я знаю. Это одна из реализаций.
Система в данном случае модульная, в файлах ставится признак чем архивирован, и в зависимости от этого можно уже делать действия, если имеет смысл zip то можно делать так. Наверное для больших файлов zip-ом в будущем и сделаю. Тут везде должен быть вопрос целесообразности.

Да ну? Вы для программистов статью написали или для менеджеров?)

Да, вы правы, это я погорячился )

Эмм. Чем это отличается от таблицы tasks__files (task_id, file_id, ...)?

По-моему, промежуточные таблицы для связи для связи многие-ко-многим больше подходят. Они явно показывают принадлежность файла к сущности.

И да и нет. Можно и так, но в моем случае например лучше через хэши. У меня встроенный язык программирования и файлы могут быть приложены где угодно в системе, в любом месте страницы любого раздела, даже в нескольких местах на одной странице + должны учитываться входные данные в страницу, например у одной задачи одни файлы, у другой дургие. Входные данные — может быть тоже не один параметр а 2-а,3-и...,10-ять. Поэтому удобнее было через хэши. Он всегда будет уникальный у уникальных данных. Да и в смысле быстродействия на мой взгляд лучше, индекс по одному полю с уникальными значениями.
Но реализация через таблицы многие-ко-многим — тоже вполне может иметь место.
Да можно как угодно обозвать. Это просто пример. Но вообще я всегда пишу «Data» (тут автоматом тоже так обозвал) ибо «Date» — зарезервированное слово, оно в любом случае с приставкой какой-то должно идти. Можно конечно с кавычками, но это просто неудобно.

GridFS — как вариант. Но когда мне пришлось все это делать, я просто не знал о ней. Возможно я бы тогда и не заморачивался своей системой.
Но видите, во всем своя польза, получилась альтернативная структура, которую можно сделать самостоятельно. В свое время я никакой подробной статьи по использованию blob полей для хранения файлов не нашел. Вот написал ее, пусть будет.
lair — тут нет требования к проф среде разработки. Главное предназначение этого механизма — корректировки нюансов. Он дает пользователям потрясающую гибкость.
Все пытаются сделать системы, чтобы ее структура подходила всем компаниям, а такого не бывает. У каждой компании свой уникальный бизнес-процесс. Можно сделать что-то среднее — подходящее примерно всем, но как известно — дьявол кроется в нюансах. Нюансы бизнес-процессов копании никогда не угадаете. Но используя такие средства редактирования можно их довольно просто реализовать.

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

Тесты — есть система запуска процедуры и просмотра предварительного результата. Для запросов работает очень удобно. Для отладки добавления или удаления данных такое подходит не очень, согласен. Но этого как правило не требуется, я пока не сталкивался чтобы это понадобилось.

Вообще добавления и редактирования давно с нуля не делал чтобы отлаживать. У меня есть очень удобный механизм созадния типовых процедур мегаупрощающий разработку. После создания таблицы можно просто нажать кнопочку «Создать типовые процедуры» и система создаст 5 процедур к этой таблице: Вывод всех данных, Вывод строки, Редактирование строки, Добавление строки, Удаление строки. Там уже будут прописаны все переменные вашей таблицы, весь функционал. Во многих случаях этого даже достаточно. Если требуется что-то немного другое, какие-то фильтры, просто процедура нужная доредактируется. Это намного быстрее и проще.
Можно в процедуру импортировать все переменные с набором из таблицы, можно заполнить вывод селекта по сопоставлению имен переменных.
В общем на самом деле разрабатывать тут гораздо быстрее чем в IBExperte. В нем чтобы сделать процедуру к таблице: давай прописывать переменные и типы данных их на вход-выход, потом перечислять их в select, потом пречислять их в into. На это пипец времени уходит впустую. Я уже забыл что это такое. У меня бывает что целый небольшой модуль в течении часа появляется.
Ну на мой взгляд разработать такую систему для того чтобы логировать более просто — весьма непросто. Проще уж 3 таблички в БД создать :)
Но вы правы, теоретически ваша версия имеет право на жизнь. Просто получится альтернативная технологическая платформа.
Но что из этого «овер-инженеринг» большой вопрос :)
А по конкретнее можете описать, что было отвратительного? Мне просто действительно интересно.

И что за система? Я кроме 1С с подобной концепцией никого не знаю. А тем более с реализацией через веб.
Нет. Совершенно не так. Есть 2 части:

1. Пользователь у меня может полностью программировать структуру БД, создавать таблицы, делать процедуры, триггеры. Абсолютно любой сложности и вложенности. Здесь по сути SQL — только не совсем, логика таже, но реализовано это через веб при помощи постройки определенных элементов. SQL запросов (в вашем понимании, как текст) тут нет. Выглядит примерно так, но тут очень простой пример. Более сложное просто в принтскрин не влезет. Поддерживаются любые структуры и компануются они в древовидную структуру определенной последовательность выполнения. Потом идет процесс компилирования — в БД создается нужная процедура из этого.

2. Пользователь может произвольно редактировать веб интерфейс, выводить в элементы интерфейса данные из своих процедур, создавать элементы управления, связывать эти элементы с конкретными процедурами в БД. И т.д. Тут двумя словами не описать. Но тут все делается исключительно редактором при помощи кнопочек, никакого произвольного php текста.
У меня есть справка, Часть 3 и 4 посмотрите если интересно. Но я пока по программированию далеко не все описал. Описана только частично программирование в БД, к описанию веба я пока не приступал. Только оглавление. Думаю в течении 2-3 недель будет описание полное. Пока работаю еще над этим. Очень много работы помимо этого.
Это не значит, что они правильные — это значит, что вы натягиваете решения в зону своей экспертизы.


Статья извиняюсь про БД и в разделе БД.

А что, создание задач в БД чем-то отличается?


По безопасности конечно отличается. В БД по сути только исключать вопросы sql-иньекций и бесконечных циклов. Изолировать возможность деятельности только конкретной базой.
А давать программировать на php неизвестному юзеру на вашем сервере — ну наверное возможно, но в весьма урезанной версии, исключить опасные команды, в общем это намного сложнее на мой взгляд проконтролировать.

Information

Rating
Does not participate
Registered
Activity