一、首先我们要分析影响odoo 服务器 性能的因素
- 配置建议
官方技术支持文档请参考 https://www.odooai.cn/documentation/16.0/zh_CN/administration.html
参考odoo官方文档,做好主机及网络配置。按我们实际运营经验,Odoo正常运营的最低配置建议为4核16G的独享主机,请使用主流CPU(与当前最新CPU代差不超过3代)。
- 用户及并发计算, Workers 计算
可用odoo worker =(#CPU * 2) + 1
Cron队列也需要占用 workers
1 个worker ~= 6 个并发用户
- 内存大小计算
我们认为 20% 的请求是复杂请求,而 80% 是简单请求。
一个复杂繁重的Worker,当所有计算字段都设计得很好,SQL请求设计得很好,…估计消耗约1GB的内存
在相同的情况下,较轻的工作线程估计会消耗大约150MB的RAM。
所需内存= #worker *(( 简单请求占比 * 150M)+ (复杂请求占比 * 1000M))
- 应用层
这是最主要和最常见的原因,odoo在做数据导入或者数据操作时,一般都是调用ORM中的create和write方法的,会触发安全检查、约束检查、数据Compute等。了解这个核心就好处理了。
- CPU
目前大部分CPU在同一时间只能运行一个线程,超线程的处理器可以在同一时间处理多个线程,因此可以利用超线程特性提高系统性能。
在linux系统下只有运行SMP内核才能支持超线程,但是安装的CPu数量越多,从超线程获得的性能提升越少。
odoo单进程模式下对 CPU 要求并不高,但是为了支持多并发,需要开启 workers,一般
work 数量为 works = 2 * cpu(核) + 1
- 内存说明
内存太小,系统进程将被阻塞,应用也将变得缓慢,甚至失去响应;内存太大,导致资源浪费。
虚拟内存可以缓解物理内存的不足,但是虚拟内存的过多占用会导致应用程序的性能明显下降。
在一个32位处理器的linux系统中超过8GB的物理内存都将被浪费,因此要使用更大的内存,建议安装64位的操作系统,同时开启linux的大内存内核支持。
由于处理器寻址范围的限制,在32位linux操作系统上,应用程序单个进程最大只能使用2GB的内存。
oodo 一般建议部署在 64 位环境中,内存数量和 odoo 开启的 worker 数量成正比,odoo 有个稍微复杂的估算,一般建议简单用下列方法核算:
works * 75
例如
- 磁盘I/O性能
磁盘RAID技术,Redundant Array of Independent Disk,即独立磁盘冗余阵列,简称磁盘阵列。
RAID通过将多块独立的磁盘(物理硬盘)按不同的方式组合起来形成一个磁盘组(逻辑硬盘),从而提供比单个磁盘更高的IO性能和数据冗余。
根据磁盘组合方式不同,分为RAID0、RAID1、RAID2、RAID3、RAID4、RAID5、RAID6、RAID7、RAID0+1、RAID10等,常用的有RAID0、RAID1、RAID5、RAID0+1。
RAID0:通过把多块硬盘粘合成一个容量更大的硬盘组,提高磁盘的性能和吞吐量,成本低,至少两块磁盘,但是没有容错和数据修复功能,只能用在对数据安全性要求不高的环境中。
RAID1:也就是磁盘镜像,通过把一个磁盘的数据镜像到另外一个磁盘上,最大限度的保证磁盘数据的可靠性和可修改性,具有很高的数据冗余能力,但是磁盘利用率只有50%,成本较高,多用在保存重要数据的场合。
RAID5:磁盘分段加奇偶校验技术,提高了系统的可靠性。读出效率很高,写效率一般,至少需要3块磁盘,允许一块磁盘故障,不影响数据的可用性。
RAID0+1:把RAID0和RAID1技术结合起来,至少需要4块硬盘,每个盘都有其镜像盘,提高全冗余能力,并具有快速读写能力。
- 网络带宽
Odoo 对带宽要求较高,一般建议 10用户 /M 带宽。
二、系统性能评估
找到影响 Odoo 性能的关键原因,才能对症下药,工欲善其事,必先利其器,需要使用一些软件和命令:
性能调试软件
odoo16自带了性能调试,开发者模式下,启用性能调试就好。需要特殊调试的使用 @profile 处理。
数据库层也是必要的,软件很多,Bing一下就可以。
应用层的优化主要涉及几个方法
1、少compute,少onchange
2、常用的模型如 res.partner,product.template,account.move,stock.move.line 等关联特别多,大数据时动刀子要小心。
3、Create时多用 multi,write时也是尽量批量处理,检查下没必要的继承。
4、聚合查询时不一定用for循环,可以用 read_group 等聚合查询。
5、可以减少安全检查,比如 compute_sudo 。减少约束或者优化,SQL约束的速度比@api 方式快不少。
6、使用缓存及减少大事务。odoo有专门的cache处理,可能参考 stock 模块,里面很多源码,也可以使用 redis。事务处理就是看准了,先 cr.commit ,确保在不影响数据完整性时尽早提交事务。
7、更好的代码处理,必要时直接SQL,具体看实际代码处理,可以通过 Ai 辅助编码, Co-pilot 这种可以用你的全局代码来优化,虽然比不上人但也省事。代码实例是 多级多物料多规格的 bom 处理,同时通过此 bom 计算 mrp,生产时通过库存算补货,这些都是极其费资源的。
if len(vals_list):
# self.bom_line_ids.with_context(quick_create_bome_line=True).create(sorted(vals_list, key=lambda v: v['size']))
# 调整为sql,单行即可,不需要批量,速度影响不大,要进行更多的检验数据
for vals in vals_list:
i_fields = ','.join(vals.keys())
i_values = ','.join(map(str, vals.values()))
sql = "insert into mrp_bom_line(%s) values (%s);" % (i_fields, i_values)
# _logger.warning('=============== 4 create bom_line_ids sql: %s' % sql)
self._cr.execute(sql)
常用系统命令
Vmstat、sar、iostat、netstat、free、ps、top等
常用组合方式
l
l
l
l
1:系统整体性能评估(uptime命令)
[root@web1 ~]# uptime
16:38:00 up 118 days,
2:cpu性能评估
(1)利用vmstat命令监控系统CPU
[root@node1 ~]# vmstat 2 3
procs
Procs
r列表示运行和等待cpu时间片的进程数,这个值如果长期大于系统CPU的个数,说明CPU不足,需要增加CPU。
b列表示在等待资源的进程数,比如正在等待I/O、或者内存交换等。
Cpu
us列显示了用户进程消耗的CPU 时间百分比。us的值比较高时,说明用户进程消耗的cpu时间多,但是如果长期大于50%,就需要考虑优化程序或算法。
sy列显示了内核进程消耗的CPU时间百分比。Sy的值较高时,说明内核消耗的CPU资源很多。
(2) 利用sar命令监控系统CPU
sar功能很强大,可以对系统的每个方面进行单独的统计,但是使用sar命令会增加系统开销,不过这些开销是可以评估的,对系统的统计结果不会有很大影响。
[root@webserver ~]# sar -u 3 5 #u显示系统所有cpu在采样时间内的负载状态
Linux 2.6.9-42.ELsmp (webserver)
11:41:24 AM
11:41:27 AM
11:41:30 AM
11:41:33 AM
11:41:36 AM
11:41:39 AM
Average:
对上面每项的输出解释如下:
l
l
l
l
l
l
3:内存性能评估
(1)利用free指令监控内存
free是监控linux内存使用状况最常用的指令,看下面的一个输出:
[root@webserver ~]# free
Mem:
-/+ buffers/cache:
Swap:
(2) 利用vmstat命令监控内存
[root@node1 ~]# vmstat 2 3
procs -----------memory----------
memory
swpd列表示切换到内存交换区的内存数量(以k为单位)。如果swpd的值不为0,或者比较大,只要si、so的值长期为0,这种情况下一般不用担心,不会影响系统性能。
free列表示当前空闲的物理内存数量(以k为单位)
buff列表示buffers cache的内存数量,一般对块设备的读写才需要缓冲。
cache列表示page cached的内存数量,一般作为文件系统cached,频繁访问的文件都会被cached,如果cache值较大,说明cached的文件数较多,如果此时IO中bi比较小,说明文件系统效率比较好。
swap
si列表示由磁盘调入内存,也就是内存进入内存交换区的数量。
so列表示由内存调入磁盘,也就是内存交换区进入内存的数量。
一般情况下,si、so的值都为0,如果si、so的值长期不为0,则表示系统内存不足。需要增加系统内存。
4:磁盘I/O性能评估
(1)磁盘存储基础
l
l
l
l
ü
ü
ü
ü
ü
(2)利用iostat评估磁盘性能
[root@webserver ~]#
Linux 2.6.9-42.ELsmp (webserver)
Device:
sda
Device:
sda
Device:
sda
对上面每项的输出解释如下:
Blk_read/s表示每秒读取的数据块数。
Blk_wrtn/s表示每秒写入的数据块数。
Blk_read表示读取的所有块数。
Blk_wrtn表示写入的所有块数。
- 可以通过Blk_read/s和Blk_wrtn/s的值对磁盘的读写性能有一个基本的了解,如果Blk_wrtn/s值很大,表示磁盘的写操作很频繁,可以考虑优化磁盘或者优化程序,如果Blk_read/s值很大,表示磁盘直接读取操作很多,可以将读取的数据放入内存中进行操作。
- 对于这两个选项的值没有一个固定的大小,根据系统应用的不同,会有不同的值,但是有一个规则还是可以遵循的:长期的、超大的数据读写,肯定是不正常的,这种情况一定会影响系统性能。
(3)利用sar评估磁盘性能
[root@webserver ~]# sar -d 2 3
Linux 2.6.9-42.ELsmp (webserver)
11:09:33 PM
11:09:35 PM dev8-0
11:09:35 PM
11:09:37 PM dev8-0
11:09:37 PM
11:09:39 PM dev8-0
Average:
Average:
await表示平均每次设备I/O操作的等待时间(以毫秒为单位)。
svctm表示平均每次设备I/O操作的服务时间(以毫秒为单位)。
%util表示一秒中有百分之几的时间用于I/O操作。
对以磁盘IO性能,一般有如下评判标准:
正常情况下svctm应该是小于await值的,而svctm的大小和磁盘性能有关,CPU、内存的负荷也会对svctm值造成影响,过多的请求也会间接的导致svctm值的增加。
await值的大小一般取决与svctm的值和I/O队列长度以及I/O请求模式,如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好,如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢,此时可以通过更换更快的硬盘来解决问题。
%util项的值也是衡量磁盘I/O的一个重要指标,如果%util接近100%,表示磁盘产生的I/O请求太多,I/O系统已经满负荷的在工作,该磁盘可能存在瓶颈。长期下去,势必影响系统的性能,可以通过优化程序或者通过更换更高、更快的磁盘来解决此问题。
5:网络性能评估.
(1)通过ping命令检测网络的连通性
(2)通过netstat –i组合检测网络接口状况
(3)通过netstat –r组合检测系统的路由表信息
(4)通过sar –n组合显示系统的网络运行状态
【5】常用分析
netstat -an|awk '/^tcp/{++S[$NF]}END{for (a in S)print a,S[a]}'
netstat -pant |grep ":80"|awk '{print $5}' | awk -F: '{print $1}'|sort|uniq -c|sort -nr
cat access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -n10
提取日志
awk '{print $7}' access.log | sort | uniq -c |sort -nr | head -n10
【6】shell分析nginx日志
178.255.215.86 - - [04/Jul/2013:00:00:31 +0800] "GET /tag/316/PostgreSQL HTTP/1.1" 200 4779 "-" "Mozilla/5.0 (compatible; Exabot/3.0 (BiggerBetter); +http://www.exabot.com/go/robot)" "-"- 178.255.215.86 - - [04/Jul/2013:00:00:34 +0800] "GET /tag/317/edit HTTP/1.1" 303 5 "-" "Mozilla/5.0 (compatible; Exabot/3.0 (BiggerBetter); +http://www.exabot.com/go/robot)" "-"- 103.29.134.200 - - [04/Jul/2013:00:00:34 +0800] "GET /code-snippet/2022/edit HTTP/1.0" 303 0 "-" "Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0" "-"- 103.29.134.200 - - [04/Jul/2013:00:00:35 +0800] "GET /user/login?url=http://outofmemory.cn/code-snippet/2022/edit HTTP/1.0" 200 4748 "-" "Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0" "-"-
以下脚本都是基于上面日志格式的,如果你的日志格式不同需要调整awk后面的参数。
分析日志中的UserAgent
cat access_20130704.log | awk -F "\""
上面的脚本将分析出日志文件中最多的20个UserAgent
分析日志中那些IP访问最多
cat access_20130704.log | awk '{print $1}'
分析日志中那些Url请求访问次数最多
cat access_20130704.log | awk -F "\""
三、针对发现问题的常用改进措施
1、为磁盘I/O调整Linux内核电梯算法
2、禁用不必要的守护进程,节省内存和CPU资源
|
|
|
|
|
|
|
Nfslock | 用于NFS文件锁定 |
|
Isdn | ISDN Moderm支持 |
|
Autofs | 在后台自动挂载文件系统(如自动挂载CD-ROM) |
|
Sendmail | 邮件传输代理 |
|
Xfs | X Window的字体服务器 |
3、关掉GUI
4、清理不需要的模块或功能
5.修改磁盘缓存:Odoo 有大量的小文件,修改磁盘预读缓存可以显著 提高 odoo 访问速度
blockdev 工具允许从命令行调用区块设备控制程序。
–setro 设置设备为只读
–getro
–setrw
–getss
–getsize 打印设别的容量,按照一个扇区512个字节计算
–setra N 设置预读扇区(512字节)为N个.Set readahead to N 512-byte sectors.
–getra 打印readahead(预读扇区)
–flushbufs
–rereadpt
blockdev --getra /dev/sda
默认值为256,建议的范围是在4096-16384之间,预读不足的常见问题是写磁盘的速度要比读取的速度要高。
改变参数的命令格式是:blockdev --setra 4096 /dev/xdva1
需要根据每块磁盘单独进行设置,通常可以将调整命令写入rc.local启动脚本中。
6.在linux中,用户每访问一个文件,系统都会更新文件的其中一个属性(上次访问时间),当用户在访问数据时,系统会需要不断的进行写操作,这个在系统中也是一笔不小的开销,我们可以在/etc/fstab文件中,对挂载的卷加上noatime选项来禁用此行为:
/dev/sda1 / ext3 noatime,errors=remount-ro 0 1
修改完以后,执行sudo mount -a 命令生效即可。
7.在linux中有关读缓存与交换的参数如下有两个,可以在/etc/sysctl.conf中加上两行:
vm.swappiness=0
vm.overcommit_memory=2
这些参数可以在/proc/sys/vm/中查看
8.共享内存的设定,ubuntu中共享内存的默认值都很低,为了更好的利用服务器资源,我们将对其进行调整,网上有一个调整的脚本。
- #!/bin/bash
-
- page_size=`getconf
PAGE_SIZE` - phys_pages=`getconf
_PHYS_PAGES` - shmall=`expr
$phys_pages / 2` - shmmax=`expr
$shmall \* $page_size` - echo
kernel.shmmax = $shmmax - echo
kernel.shmall = $shmall
直接以root身份运行 ./shmsetup >> /etc/sysctl.conf
sysctl -p
9、将日志文件转移到内存中
当一台机器处于运行中时,最好是将系统日志放在内存中,当系统关闭时再将其复制到硬盘,当你运行一台开启了syslog功能的笔记本电脑或移动设备时,ramlog可以帮助你提高系统电池或移动设备闪存驱动器的寿命,使用ramlog的一个好处是,不用再担心某个守护进程每隔30秒向syslog发送一条消息,放在以前,硬盘必须随时保持运转,这样对硬盘和电池都不好。
10、先打包,后写入
在内存中划分出固定大小的空间保存日志文件,这意味着笔记本电脑硬盘不用一直保持运转,只有当某个守护进程需要写入日志时才运转,注意ramlog使用的内存空间大小是固定的,否则系统内存会很快被用光,如果笔记本使用固态硬盘,可以分配50-80MB内存给ramlog使用,ramlog可以减少许多写入周期,极大地提高固态硬盘的使用寿命。
持续更新中