FastDFS 集群和配置优化以及SpringBoot访问FastDFS

一、FastDFS集群架构设置

3台CentOS 7 虚拟机
3个tracker 3个storage
在这里插入图片描述

按照之前的单机方式先进行安装

二、FastDFS集群架构详细配置

1、配置tracker集群 三台相同

vi /etc/fdfs/tracker.conf

store_lookup=0 # 0是轮询,1是指定组,2是剩余存储空间多的group优先

2、配置storage集群

vi /etc/fdfs/storage.conf

tracker_server=192.168.211.130:22122
tracker_server=192.168.211.136:22122
tracker_server=192.168.211.135:22122
group_name=group1 #注意组名 192.168.211.135 配置是 group2
port=23000 #storage 的端口号,同一个组的 storage 端口号必须相同
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart

3、查看storage的日志 查看tracker集群信息

cat /home/fastdfs/logs/storaged.log
访问FastDFS时 可以把Tracker 理解成对等的,但实际底层多个Tracker时在运行过程中会选择其中一个作为Leader,由该Leader执行一些唯一性的操作。在早期版本中Tracker-Leader有两个作用,分别是:为新加入的Storage分配一个源Storage;为开启合并存储的Group选择Trunk-Server。但是在最新的版本中实际上只有第二个作用,也就是选择Trunk-Server。

查看之后 如果连接不上 注意防火墙

systemctl stop firewalld

4、查看存储集群信息

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

5、测试上传

vim /etc/fdfs/client.conf
tracker_server=192.168.211.130:22122
tracker_server=192.168.211.136:22122
tracker_server=192.168.211.135:22122
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /root/fastdfs/1.png
find / -name *.png

三、使用Nginx 和 FastDFS集群结合

vi /etc/fdfs/mod_fastdfs.conf

tracker_server=192.168.211.130:22122
tracker_server=192.168.211.136:22122
tracker_server=192.168.211.135:22122
group_name=group1 #注意组名 如果是group2 则一定要改

vim /usr/local/nginx/conf/nginx.conf

#添加如下配置
server {
	listen 8888;
	server_name localhost;
	location ~/group[0-9]/ {
		ngx_fastdfs_module;
	}
}

/usr/local/nginx/sbin/nginx

四、测试文件服务器

通过任意一台nginx 访问
http://192.168.211.130/group1/M00/00/00/wKjIZVyLMi6AH08jAADtXa53YW0605.png
http://192.168.211.135/group1/M00/00/00/wKjIZVyLMi6AH08jAADtXa53YW0605.png

五、FastDFS配置优化

1、 最大连接数设置

配置文件:tracker.conf 和 storage.conf
参数名:max_connections
缺省值:256
说明:FastDFS为一个连接分配一个task buffer,为了提升分配效率,FastDFS采用内存池的做法。
FastDFS老版本直接事先分配 max_connections 个buffer,这个做法显然不是太合理,在max_connections 设置过大的情况下太浪费内存。v5.04对预分配采用增量方式,tracker一次预分配
1024个,storage一次预分配256个。
#define ALLOC_CONNECTIONS_ONCE 1024
总的task buffer初始内存占用情况测算如下
	改进前:max_connections * buffer_size
	改进后:max_connections和预分配的连接中那个小 * buffer_size
使用v5.04及后续版本,可以根据实际需要将 max_connections 设置为一个较大的数值,比如 10240甚至更大。
注意此时需要将一个进程允许打开的最大文件数调大到超过max_connections否则FastDFS server启动会报错。
vi /etc/security/limits.conf 重启系统生效
* soft nofile 65535
* hard nofile 65535
另外,对于32位系统,请注意使用到的内存不要超过3GB

2、工作线程数设置

配置文件:tracker.conf 和 storage.conf
参数名: work_threads
缺省值:4
说明:为了避免CPU上下文切换的开销,以及不必要的资源消耗,不建议将本参数设置得过大。为了发挥出
多个CPU的效能,系统中的线程数总和,应等于CPU总数。
对于tracker server,公式为:
	work_threads + 1 = CPU数
对于storage,公式为:
	work_threads + 1 + (disk_reader_threads + disk_writer_threads) * store_path_count = CPU数

3、storage目录数设置

配置文件: storage.conf
参数名:subdir_count_per_path
缺省值:256
说明:FastDFS采用二级目录的做法,目录会在FastDFS初始化时自动创建。存储海量小文件,打开了
trunk存储方式的情况下,建议将本参数适当改小,比如设置为32,此时存放文件的目录数为 32 * 32 =
1024。假如trunk文件大小采用缺省值64MB,磁盘空间为2TB,那么每个目录下存放的trunk文件数均值
为:2TB/(1024 * 64MB) = 32个

4、 storage磁盘读写线程设置

配置文件: storage.conf
参数名:disk_rw_separated:磁盘读写是否分离
参数名:disk_reader_threads:单个磁盘读线程数
参数名:disk_writer_threads:单个磁盘写线程数
如果磁盘读写混合,单个磁盘读写线程数为读线程数和写线程数之和,对于单盘挂载方式,磁盘读写线程分别设置为 1即可如果磁盘做了RAID,那么需要酌情加大读写线程数,这样才能最大程度地发挥磁盘性能

5、 storage同步延迟相关设置

配置文件: storage.conf
参数名:sync_binlog_buff_interval:将binlog buffer写入磁盘的时间间隔,取值大于0,缺省值为60s
参数名:sync_wait_msec:如果没有需要同步的文件,对binlog进行轮询的时间间隔,取值大于0,缺省值为200ms
参数名: sync_interval:同步完一个文件后,休眠的毫秒数,缺省值为0
为了缩短文件同步时间,可以将上述3个参数适当调小即可

六、FastDFS 应用

1、SpringBoot访问FastDFS

  1. 引入jar依赖
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>com.github.tobato</groupId>
		<artifactId>fastdfs-client</artifactId>
		<version>1.26.1-RELEASE</version>
	</dependency>
</dependencies>
  1. 配置文件 application.yml
fdfs:
	connectTimeout: 600
	trackerList:
		- 192.168.211.130:22122
		- 192.168.211.135:22122
		- 192.168.211.136:22122
server:
	port: 8899
  1. 编写上传下载文件的服务类
@Component
public class FastDFSClientService {
	@Autowired
	private FastFileStorageClient fastFileStorageClient;
	/**
	* 文件上传
	* *
	@param bytes 文件字节
	* @param fileSize 文件大小
	* @param extension 文件扩展名
	* @return fastDfs路径
	*/
	public String uploadFile(byte[] bytes, long fileSize, String extension) {
		ByteArrayInputStream byteArrayInputStream = new
		ByteArrayInputStream(bytes);
		StorePath storePath = fastFileStorageClient.uploadFile(byteArrayInputStream,
		fileSize, extension, null);
		System.out.println(storePath.getGroup() + ":" + storePath.getPath() +
		":" + storePath.getFullPath());
		return storePath.getFullPath();
	} /
	**
	* 下载文件
	* *
	@param fileUrl 文件URL
	* @return 文件字节
	* @throws IOException
	*/
	public byte[] downloadFile(String fileUrl) throws IOException {
		String group = fileUrl.substring(0, fileUrl.indexOf("/"));
		String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
		DownloadByteArray downloadByteArray = new DownloadByteArray();
		byte[] bytes = fastFileStorageClient.downloadFile(group, path,	downloadByteArray);
		return bytes;
	}
}
  1. 控制器类
@RestController
@RequestMapping("/fastdfs")
public class FastDFSController {

	@Autowired
	private FastDFSClientService fastDFSClientService;
	
	@RequestMapping("/upload")
	public String uploadFile(MultipartFile file) throws IOException {
		byte[] bytes = file.getBytes();
		String originalFileName = file.getOriginalFilename();
		String extension =
		originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
		String fileName = file.getName();
		long fileSize = file.getSize();
		System.out.println(originalFileName + ":" + fileName + ":" + fileSize +
		":" + extension + ":" + bytes.length);
		return fastDFSClientService.uploadFile(bytes, fileSize, extension);
	} 
	@RequestMapping("/download")
	public void downloadFile(String fileUrl, HttpServletResponse response) throws IOException {
		byte[] bytes = fastDFSClientService.downloadFile(fileUrl);
		response.setHeader("Content-disposition", "attachment;filename=" +
		URLEncoder.encode(fileUrl, "UTF-8"));
		response.setCharacterEncoding("UTF-8");
		ServletOutputStream outputStream = null;
		try {
			outputStream = response.getOutputStream();
			outputStream.write(bytes);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				outputStream.flush();
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
  1. 编写启动类
//解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
//只需要一行注解就可以拥有带有连接池的FastDFS Java客户端了
@Import(FdfsClientConfig.class)
@SpringBootApplication
public class FastDfsApplicationMain {
	public static void main(String[] args) {
		SpringApplication.run(FastDfsApplicationMain.class, args);
	}
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值