前言:
我的nas是DIY版,系统是debian的omv,网上有很多教程,以前是黑裙,不喜欢盗版,喜欢开源免费,教程不表。
可以参照这个文章:https://www.noobyy.com/nas
私有云大致对比了下nextcloud和seafile,seafile加密不明文,没法smb,就用nextcloud。docker安装,1分钟搞定,美滋滋。
问题和解决过程描述:
装完之后确实可以用了,但是遇到了性能问题:局域网传输都仅有1-5M/s ,初始化数据库,网页打开都非常慢,这没法用啊。排查:
0、换版本:把nextcloud,和mariadb都换了旧版,一样没效果,不是程序代码问题,他们的程序员没那么差。
1、网络问题? smb传输可以跑到磁盘写的极限,70M/s,所以肯定不是网络问题,是程序在我的环境下遇到了什么问题。
2、top命令,负载较高,cpu很低,磁盘IO瓶颈。iotop看一下,发现apache httpd每秒写几M,但是整个磁盘每秒写50M?奇了怪了。除了apache之外,mysql的io也很高。但是加起来磁盘写也没有50M。
3、换个磁盘试试?docker挂载另一块盘,发现效果非常好,初始化快,读写速度都不错。肯定是硬盘问题。(一定用docker装啊,太快了,随便换)
解决点1:(大多数没有这个问题,可以看看,然后忽略):我的硬盘是之前黑裙糟蹋过的btrfs,甚至还组了raid,感觉一直在双写,总之不健康,性能很差,估计碎片,空洞什么的很多吧,具体我也不懂。处理他,备份数据,格式化,ext4格式,raid也没了。效果不错,局域网用1个3G的文件上传nextcloud,瞬时速度可以到30-50M每秒了,虽然不太完美,总之好多了。
新问题:之前测试都是用一个大文件,速度还不错,但是偶然间用几千个文件的文件夹拖拽上传,cpu很快上去了,IO负载很高,写入速度上不去,局域网10几兆每秒的样子,和一个大文件上传截然不同,按照程序员排查问题的经验,肯定是碎文件在不断创建和写库有性能开销。
继续看top、iotop、vmstat等:cpu 50%,io很高,mysql的IO占比很高,apache毕竟上传速度那么低,很低,mysql有点喧宾夺主了吧?
mysql在做什么,这么点速度,那么高IO。登陆mysql容器,show processlist;发现全是在做文件锁,锁这种东西用mysql sql语句不太合适吧?按照官网建议改redis,毕竟是内存。
解决点2(非常关键):给nextcloud配置redis锁(网上有很多nc性能优化都提到了这个)
docker装redis,修改config.php,增加锁的引用。
效果非常明显,sql语句只有insert 语句了,这个是正常的。IO也没之前高了。
但是硬件瓶颈这个东西,只看木桶最短板,再传文件夹,碎文件,iO虽然不是问题,但是cpu100%了,磁盘写速度从10m提升到了30M左右(我心中50-70M每秒)。还是mysql IO最高,我有点心灰意冷,认为nextcloud,除了写磁盘对mysql使用过高,吃机器性能。对比了一下其他的私有云产品,感觉还是得回来继续优化,不行就打算看看nextcloud源码,看看put方法都在做什么,能不能减少点sql调用。先尝试优化下mysql,毕竟是个硬盘读写的中间件,网上搜了搜,mysql性能优化,改了一个参数,世界美好了。
解决点3(最最关键):
mysql 进去,看看变量,SHOW VARIABLES like '%flush%' 一看, innodb_flush_log_at_trx_commit 这个参数默认是1,就是最安全,性能最差的,改成0(找到my.cnf,docker卷下找到2个,全改了,重启mysql容器),我可以接受1秒宕机,数据库丢失,因为数据库全挂了,nextcloud还可以通过scan命令重新扫描。改成2的话,就是折中,没必要,直接改成0。
性能非常完美,碎文件上传,wifi链接的情况下,50-60M每秒,硬盘瓶颈也就这样了,cpu跑满,IO最高的已经变成apache的多线程了,这个估计用nginx和phpfrm也能优化,没必要了,心累了,速度够用了。先告一段落吧。
这样的nextcloud还有点好用。
总结:整体思路就是,在硬盘和网络没问题的情况下,让程序减少使用mysql,减少sql语句,同时让mysql高性能工作,少做无用功。
主要命令:top、iotop、vmstat、iostat足够了。
后来网上看到很多人说,nextcloud太吃性能,我想对于程序员 运维之外的人群来说,确实是太吃性能了,不是做这个的,谁能知道优化mysql的刷盘策略,以及用缓存替代文件锁呢。
过程比较复杂,很多命令和细节没写,也踩了很多弯路,做了很多尝试,还有一些其他的坑,回想着列一下:
1、nextcloud日志(在data目录里)里redis报exception,说什么protected-mode保护模式,修改一下redis配置文件,改成off,重启,不报了。
2、nextcloud 任务从ajax改成cron,nas里配置cron命令,网上有文章。【对于网页打开速度能加快?】
3、mysql binlog关闭,没什么用,还是那句话,mysql挂了都没问题,有文件就可以,重新扫描,命令:docker exec nextcloud su www-data -s /bin/bash -c "php /var/www/html/occ files:scan —all” 【应该有点用】
4、ext4的硬盘jbd2进程IO占比过高,网上有优化办法,链接找不到了。【不过效果不明显】。