本文目录导读:

我来详细介绍PHP项目本地分布式存储的搭建和使用方案。
常见解决方案
1 文件系统方案
- NFS (Network File System)
- GlusterFS
- MooseFS
2 对象存储方案
- MinIO (最推荐)
- SeaweedFS
- FastDFS
MinIO 搭建方案(推荐)
1 单机多节点部署
# 下载MinIO wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod +x minio # 启动多个实例(模拟分布式) # 节点1 minio server /data/node1 --console-address :9001 # 节点2 minio server /data/node2 --console-address :9002 # 节点3 minio server /data/node3 --console-address :9003
2 Docker部署
# docker-compose.yml
version: '3.7'
services:
minio1:
image: minio/minio:latest
hostname: minio1
volumes:
- ./data1:/data
ports:
- "9001:9001"
- "9000:9000"
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: admin123
command: server /data --console-address ":9001"
minio2:
image: minio/minio:latest
hostname: minio2
volumes:
- ./data2:/data
ports:
- "9002:9002"
- "9003:9003"
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: admin123
command: server /data --console-address ":9002"
PHP 集成代码
1 安装依赖
composer require aws/aws-sdk-php # 或 composer require minio/minio-php
2 MinIO PHP客户端
<?php
// MinIO 配置类
class MinioConfig {
private static $instance = null;
private $client;
private function __construct() {
$this->client = new Minio\MinioClient(
'http://localhost:9000', // 任意节点地址
'admin', // Access Key
'admin123' // Secret Key
);
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getClient() {
return $this->client;
}
}
// 文件上传类
class FileStorage {
private $client;
private $bucket;
public function __construct($bucket = 'uploads') {
$this->client = MinioConfig::getInstance()->getClient();
$this->bucket = $bucket;
$this->initBucket();
}
private function initBucket() {
if (!$this->client->bucketExists($this->bucket)) {
$this->client->makeBucket($this->bucket);
// 设置公开读权限
$policy = json_encode([
'Version' => '2012-10-17',
'Statement' => [
[
'Effect' => 'Allow',
'Principal' => ['AWS' => ['*']],
'Action' => ['s3:GetObject'],
'Resource' => ["arn:aws:s3:::{$this->bucket}/*"]
]
]
]);
$this->client->setBucketPolicy($this->bucket, $policy);
}
}
public function upload($localPath, $remotePath = null) {
try {
$remotePath = $remotePath ?: basename($localPath);
$result = $this->client->putObject(
$this->bucket,
$remotePath,
fopen($localPath, 'rb'),
null
);
return [
'success' => true,
'path' => $remotePath,
'url' => $this->getUrl($remotePath)
];
} catch (Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function uploadFromContent($content, $remotePath) {
try {
$result = $this->client->putObject(
$this->bucket,
$remotePath,
$content,
null
);
return [
'success' => true,
'path' => $remotePath,
'url' => $this->getUrl($remotePath)
];
} catch (Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function getUrl($path) {
return "http://localhost:9000/{$this->bucket}/{$path}";
}
public function delete($path) {
try {
$this->client->removeObject($this->bucket, $path);
return ['success' => true];
} catch (Exception $e) {
return ['success' => false, 'error' => $e->getMessage()];
}
}
public function listFiles($prefix = '') {
$objects = $this->client->listObjects($this->bucket, $prefix);
$files = [];
foreach ($objects as $obj) {
$files[] = [
'name' => $obj->getKey(),
'size' => $obj->getSize(),
'modified' => $obj->getLastModified()
];
}
return $files;
}
}
3 AWS S3协议兼容(推荐)
<?php
// 使用 AWS SDK (兼容 MinIO)
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
class DistributedStorage {
private $s3;
private $bucket;
public function __construct() {
$this->s3 = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
'endpoint' => 'http://localhost:9000', // MinIO地址
'use_path_style_endpoint' => true,
'credentials' => [
'key' => 'admin',
'secret' => 'admin123',
],
]);
$this->bucket = 'myapp';
$this->initBucket();
}
private function initBucket() {
if (!$this->s3->doesBucketExist($this->bucket)) {
$this->s3->createBucket(['Bucket' => $this->bucket]);
}
}
public function uploadFile($source, $destination) {
try {
$result = $this->s3->putObject([
'Bucket' => $this->bucket,
'Key' => $destination,
'SourceFile' => $source,
'ACL' => 'public-read'
]);
return [
'success' => true,
'url' => $result['ObjectURL'],
'etag' => $result['ETag']
];
} catch (AwsException $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
public function uploadFromStream($stream, $destination) {
try {
$result = $this->s3->putObject([
'Bucket' => $this->bucket,
'Key' => $destination,
'Body' => $stream,
'ACL' => 'public-read'
]);
return ['success' => true, 'url' => $result['ObjectURL']];
} catch (Exception $e) {
return ['success' => false, 'error' => $e->getMessage()];
}
}
public function getPresignedUrl($path, $expires = '+1 hour') {
$command = $this->s3->getCommand('GetObject', [
'Bucket' => $this->bucket,
'Key' => $path
]);
$request = $this->s3->createPresignedRequest($command, $expires);
return (string) $request->getUri();
}
public function deleteFile($path) {
try {
$this->s3->deleteObject([
'Bucket' => $this->bucket,
'Key' => $path
]);
return ['success' => true];
} catch (Exception $e) {
return ['success' => false, 'error' => $e->getMessage()];
}
}
}
使用示例
<?php
// 上传文件
$storage = new DistributedStorage();
// 上传本地文件
$result = $storage->uploadFile('/path/to/local/file.jpg', 'images/2024/01/file.jpg');
echo $result['url']; // 返回访问URL
// 上传二进制数据
$imageData = file_get_contents('https://example.com/image.jpg');
$result = $storage->uploadFromStream($imageData, 'images/remote.jpg');
// 生成临时访问链接
$url = $storage->getPresignedUrl('images/2024/01/file.jpg', '+1 day');
// 删除文件
$result = $storage->deleteFile('images/old.jpg');
配置优化
1 Nginx反向代理
upstream minio_servers {
server 127.0.0.1:9000;
server 127.0.0.1:9003;
server 127.0.0.1:9006;
}
server {
listen 80;
server_name storage.example.com;
location / {
proxy_pass http://minio_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 大文件上传
client_max_body_size 100M;
client_body_buffer_size 128k;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
}
}
2 配置PHP
; php.ini upload_max_filesize = 100M post_max_size = 100M max_execution_time = 300 memory_limit = 256M
性能优化建议
1 本地缓存
<?php
class CacheStorage extends DistributedStorage {
private $cacheDir = '/tmp/file-cache';
private $cacheTime = 3600; // 缓存1小时
public function __construct() {
parent::__construct();
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
public function getFile($path) {
$cachePath = $this->cacheDir . '/' . md5($path);
// 检查缓存
if (file_exists($cachePath) && (time() - filemtime($cachePath)) < $this->cacheTime) {
return file_get_contents($cachePath);
}
// 从分布式存储获取
$result = $this->s3->getObject([
'Bucket' => $this->bucket,
'Key' => $path
]);
$content = $result['Body']->getContents();
file_put_contents($cachePath, $content);
return $content;
}
}
2 异步上传
<?php
// 使用队列异步处理上传
class AsyncUploader {
private $queue;
public function __construct() {
// 使用Redis或其他队列
$this->queue = new RedisQueue();
}
public function queueUpload($localPath, $remotePath = null) {
$remotePath = $remotePath ?: basename($localPath);
$this->queue->push([
'action' => 'upload',
'local_path' => $localPath,
'remote_path' => $remotePath,
'timestamp' => time()
]);
return ['queued' => true, 'path' => $remotePath];
}
public function processQueue() {
while ($job = $this->queue->pop()) {
$storage = new DistributedStorage();
$storage->uploadFile($job['local_path'], $job['remote_path']);
}
}
}
故障恢复
<?php
class ReliableStorage {
private $backups = [];
public function uploadWithBackup($source, $destination, $backupCount = 2) {
$result = [];
// 上传到主存储
$storage = new DistributedStorage();
$result['primary'] = $storage->uploadFile($source, $destination);
// 创建备份
for ($i = 1; $i <= $backupCount; $i++) {
$backupPath = $destination . ".backup{$i}";
$this->backups[] = [
'path' => $backupPath,
'timestamp' => time()
];
$result['backup_' . $i] = $storage->uploadFile($source, $backupPath);
}
return $result;
}
public function getWithFallback($path) {
$storage = new DistributedStorage();
try {
return $storage->getFile($path);
} catch (Exception $e) {
// 尝试从备份恢复
foreach ($this->backups as $backup) {
if (strpos($backup['path'], $path) === 0) {
try {
return $storage->getFile($backup['path']);
} catch (Exception $e) {
continue;
}
}
}
throw new Exception("文件无法恢复");
}
}
}
注意事项
- 数据一致性:确保所有节点数据同步
- 备份策略:定期备份重要数据
- 监控告警:监控存储节点状态
- 性能测试:根据业务需求调整配置
- 安全设置:配置防火墙和访问控制
这种分布式存储方案可以提供高可用性和可扩展性,适合大规模文件存储场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播