Tuesday, October 30, 2018

performance - Slow sequential speeds on 9x7-drive raidz2 (ZFS ZoL 0.8.1)

I'm running a large ZFS pool built for 256K+ request size sequential reads and writes via iSCSI (for backups) on Ubuntu 18.04. Given the need for high throughput and space efficiency, and less need for random small-block performance, I went with striped raidz2 over striped mirrors.



However, the 256K sequential read performance is far lower than I would have expected (100 - 200MBps, peaks up to 600MBps). When the zvols are hitting ~99% iowait in iostat, the backing devices typically run between 10 and 40% iowait, which suggests to me the bottleneck is something I'm missing in configuration, given it shouldn't be the backplane or CPUs in this system, and sequential workloads shouldn't work the ARC too hard.



I've played quite a bit with module parameters (current config below), read hundreds of articles, issues on OpenZFS github, etc. Tuning prefetch and aggregation got me to this performance level - by default, I was running at about ~50MBps on sequential reads as ZFS was sending TINY requests to the disks (~16K). With aggregation and prefetch working OK (I think), disk reads are much higher, around ~64K on average in iostat.



NICs are LIO iscsi target with cxgbit offload + Windows Chelsio iscsi initiator work well outside the ZFS zvols, with a optane directly mapped returning nearly full line-rate on the NICs (~3.5GBps read and write).



Am I expecting too much? I know ZFS prioritizes safety over performance, but I'd expect a 7x9 raidz2 to provide better sequential reads than a single 9-drive mdadm raid6.




System specs and logs / config files:



Chassis: Supermicro 6047R-E1R72L
HBAs: 3x 2308 IT mode (24x 6Gbps SAS channels to backplanes)
CPU: 2x E5-2667v2 (8 cores @ 3.3Ghz base each)
RAM: 128GB, 104GB dedicated to ARC
HDDs: 65x HGST 10TB HC510 SAS (9x 7-wide raidz2 + 2 spares)
SSDs: 2x Intel Optane 900P (partitioned for mirrored special and log vdevs)
NIC: Chelsio 40GBps (same as on initiator, both using hw offloaded iSCSI)
OS: Ubuntu 18.04 LTS (using latest non-HWE kernel that allows ZFS SIMD)

ZFS: 0.8.1 via PPA
Initiator: Chelsio iSCSI initiator on Windows Server 2019


Pool configuration:



ashift=12
recordsize=128K (blocks on zvols are 64K, below)
compression=lz4
xattr=sa

redundant_metadata=most
atime=off
primarycache=all


ZVol configuration:



sparse
volblocksize=64K (matches OS allocation unit on top of iSCSI)



Pool layout:



7x 9-wide raidz2
mirrored 200GB optane special vdev (SPA metadata allocation classes)
mirrored 50GB optane log vdev


/etc/modprobe.d/zfs.conf:




# 52 - 104GB ARC, this system does nothing else
options zfs zfs_arc_min=55834574848
options zfs zfs_arc_max=111669149696

# allow for more dirty async data
options zfs zfs_dirty_data_max_percent=25
options zfs zfs_dirty_data_max=34359738368

# txg timeout given we have plenty of Optane ZIL
options zfs zfs_txg_timeout=5


# tune prefetch (have played with this 1000x different ways, no major improvement except max_streams to 2048, which helped, I think)
options zfs zfs_prefetch_disable=0
options zfs zfetch_max_distance=134217728
options zfs zfetch_max_streams=2048
options zfs zfetch_min_sec_reap=3
options zfs zfs_arc_min_prefetch_ms=250
options zfs zfs_arc_min_prescient_prefetch_ms=250
options zfs zfetch_array_rd_sz=16777216


# tune coalescing (same-ish, increasing the read gap limit helped throughput in conjunction with low async read max_active, as it caused much bigger reads to be sent to the backing devices)
options zfs zfs_vdev_aggregation_limit=16777216
options zfs zfs_vdev_read_gap_limit=1048576
options zfs zfs_vdev_write_gap_limit=262144

# ZIO scheduler in priority order
options zfs zfs_vdev_sync_read_min_active=1
options zfs zfs_vdev_sync_read_max_active=10
options zfs zfs_vdev_sync_write_min_active=1
options zfs zfs_vdev_sync_write_max_active=10

options zfs zfs_vdev_async_read_min_active=1
options zfs zfs_vdev_async_read_max_active=2
options zfs zfs_vdev_async_write_min_active=1
options zfs zfs_vdev_async_write_max_active=4

# zvol threads
options zfs zvol_threads=32


I'm tearing my hair out on this. Pressure's on from users to go all-Windows with Storage Spaces, but I've used parity storage spaces (even with Storage Spaces Direct with mirrors on top), and it's not pretty either. I'm tempted to go straight mdadm raid60 under iSCSI, but would love it if someone could point out something boneheaded I'm missing that will unlock performance with the bitrot protection of ZFS :)

zfs - What is the best private cloud storage setup

I need to create a private cloud and I'm searching for the best setup.
These are my 2 most important requirements
1. Disk and system redundant
2. Price / GB as low as possible



The system is going to be used as backup setup which will receive data 24/7 over SFTP and rsync. High throughput is not that important.



I'm planning to use glusterfs and consumer grade 4TB hard-drives.



I have worked out 3 possible setups





  1. 3 servers with 11 4TB HDD
    Setup up a replica 3 glusterfs and setup each hard drive as a separate ext4 brick.
    Total capacity: 44TB
    HDD / TB ratio of 0.75 (33HDD / 44TB)


  2. 2 servers with 11 4TB HDD
    The 11 hard-drives are combined in a RAIDZ3 ZFS storage pool. With a replica 2 gluster setup.
    Total capacity: 32TB (+ zfs compression)
    HDD / TB ratio of 0.68 (22HDD / 32TB)



  3. 3 servers with 11 4TB consumer hard-drives
    Setup up a replica 3 glusterfs and setup each hard-drive as a separate zfs storage pool and export each pool as a brick.
    Total capacity: 32TB (+ zfs compression)
    HDD / TB ratio of 0.68 (22HDD / 32TB) (Cheapest)




My remarks and concerns:
If a hard drive fails which setup will recover the quickest? In my opinion setup 1 and 3 because there only the contents of 1 hard-drive needs to be copied over the network. Instead of setup 2 were the hard-drive needs te be reconstructed by reading the parity of all the other harddrives in the system.
Will a zfs pool on 1 harddrive give me extra protection against for example bit rot?
With setup 1 and 3 I can loose 2 systems and still be up and running with setup 2 I can only loose 1 system.

When I use ZFS I can enable compression which will give me some extra storage.

Monday, October 29, 2018

IMAP and Office 365 Email in One domain

I have been hosting a site for a client for 4 years and this year they Added Office 365 to the domain. When we put in the DNS records, all of the IMAP accounts I had stopped working. Is there a way to keep the domain specific IMAP accounts along with Office 365? The accounts were admin and support for customers of the clients site. To continue to use those IMAP accounts, I have to use THEIR Office 365 which I prefer not to do (I am a contractor for the company).



Any thoughts on how to amend DNS to allow for both Office 365 and domain IMAP?

email - Postfix rejects all incoming mail (Client host rejected: Access denied)



I've setup a working postfix server except that all incoming mail is rejected.




When I try to send mail via telnet:



MAIL FROM: 
250 2.1.0 Ok
RCPT TO:
554 5.7.1 : Client host rejected: Access denied


My postconf -n




alias_database = hash:/etc/postfix/aliases
alias_maps = hash:/etc/postfix/aliases
append_dot_mydomain = no
biff = no
broken_sasl_auth_clients = no
config_directory = /etc/postfix
delay_warning_time = 4h
inet_interfaces = all
mailbox_size_limit = 0
masquerade_domains = mail.mydomain.com www.mydomain.com

maximal_backoff_time = 8000s
maximal_queue_lifetime = 7d
minimal_backoff_time = 1000s
mydestination =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = techxonline.net
readme_directory = no
recipient_delimiter = +
relayhost =
smtp_helo_timeout = 60s

smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name
smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org, reject_rbl_client blackholes.easynet.nl, reject_rbl_client dnsbl.njabl.org
smtpd_data_restrictions = reject_unauth_pipelining
smtpd_hard_error_limit = 12
smtpd_helo_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_hostname, reject_invalid_hostname, permit
smtpd_recipient_limit = 16
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain =

smtpd_sasl_security_options = noanonymous
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_pipelining, permit
smtpd_soft_error_limit = 3
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes
unknown_local_recipient_reject_code = 450
virtual_alias_maps = mysql:/etc/postfix/mysql_alias.cf
virtual_gid_maps = static:5000

virtual_mailbox_base = /var/spool/mail/virtual
virtual_mailbox_domains = mysql:/etc/postfix/mysql_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_mailbox.cf
virtual_uid_maps = static:5000


In /var/log/syslog after sending from Gmail:



Oct 18 21:30:01 appman postfix/smtpd[25307]: connect from mail-gx0-f181.google.com[209.85.161.181]
Oct 18 21:30:01 appman postfix/smtpd[25307]: NOQUEUE: reject: RCPT from mail-gx0-f181.google.com[209.85.161.181]: 554 5.7.1 : Client host rejected: Access denied; from= to= proto=ESMTP helo=
Oct 18 21:30:01 appman postfix/smtpd[25307]: disconnect from mail-gx0-f181.google.com[209.85.161.181]



How can I get my postfix server to accept mail? If there is any other information I can provide please let me know.



EDIT:
It seems like the server is requiring authentication to receive mail here. It doesn't seem to be host-restricted—using telnet from the server itself still causes the mail to be rejected. Authenticating with SASL and then sending the email works fine.



So, it seems that the problem is the server expects authentication for mail to be delivered at the final destination, which it shouldn't. Ideas?


Answer



I think you need to put mydestination = mydomain.com in your config.







Next guess: We know the domain is right and that SASL works... so what I now suspect is that we're seeing an error in your restrictions. I'd start with recipient_restrictions and remove every rejection after permit_sasl_authenticated. If that works, add them back one at a time. If not, your next test is sender_restrictions.


web server - Should use EXT4 or XFS to be able to 'sync'/backup to S3?



It's my first message here, so bear with me...



(I have already checked quite a few of the "Related Questions" suggested by the editor)



Here's the setup,




  • a brand new dedicated server (8GB RAM, some 140+ GB disk, Raid 1 via HW controller, 15000 RPM)


  • it's a production web server (with MySQL in it, too, not just serving web requests); not a personal desktop computer or similar.

  • Ubuntu Server 64bit 10.04 LTS



We have an Amazon EC2+EBS setup with the EBS volume formatted as XFS for easily taking snapshots to S3, via AWS' console.



We are now migrating to the dedicated server and I want to be able to backup our data to Amazon's S3. The main reason being the possibility of using the latest snapshot from an EC2 instance in case of hardware failure on the dedicated server.



There are two approaches I am thinking of:





  1. do a "simple" file-based backup with rsync, dumping the database' and other files, and uploading to amazon via S3 API commands, or to an EC2 instance, or something.

  2. do a file-system "freeze" (using XFS) with the usual ebs/ec2 snapshot tool to take part of the file system, take a snapshot, and upload it to Amazon.



Here's my question (or series of questions):




  1. Can I safely use XFS for the whole system as the main and only format on the dedicated server?

  2. If not, is it safe to use EXT4? Or should I use something else?


  3. would then be possible to make snapshots of the system to upload to Amazon?

  4. Is it possible/feasible/practical to do what I want to do, anyway?

  5. any recommendations?



When searching around for S3/EBS/XFS, anything relevant to my problem is usually focused on taking snapshots of a XFS system that is already an EBS volume. My intention is to do it in a "real"/metal dedicated server.






Update: I just saw this on Wikipedia:





XFS does not provide direct support for snapshots, as it expects the snapshot process to be implemented by the volume manager.




I had always assumed that I could choose 2 ways of doing snapshots: via LVM or via XFS (without LVM). After reading this, I realize these 2 options are more like it:




  1. With XFS: 1) do xfs_freeze; 2) copy the frozen files via, eg, rsync; 3) unfreeze xfs

  2. With LVM and XFS: 1) do xfs_freeze; 2) make a binary copy of the frozen fs via lvcreate and related commands; 3) unfreeze xfs; 4) somehow backup the LVM snapshot.







Thanks a lot in advance,



Let me know if I need to clarify something.


Answer



Every linux filesystem (ext2, ext3, ext4, xfs, jfs, raiserfs) in current kernel can be frozen, but it must be placed on LVM first.




If you have LVM, making a snapshot automatically freezes the FS for the time it takes to make the snapshot -- it's better than doing only a freeze (your data is still available for writing and will not break the backup) and much better than simple rsync (as it will copy files in a consistent state).



Other questions:



XFS is safe, but can be problematic if you don't disable write cache or don't have battery backed cache (only ext3 is quite resilient to that)



Yes, ext4 is considered safe now. Choosing a FS mainly depends on the kind of workload you'll experience. XFS is slow with small files, very fast with large files.


linux - DBRD dual primary Heartbeat resource management

I have the following setup:





  • Two servers with DRBD running dual primary with OCFS2

  • Heartbeat with two virtual ips, one for each server

  • Round robin DNS to load balance NFS across the two vIPs



Shutting down Server1 for a period of time, cause Server2 to take over the vIP for failover. However, when Server1 returns - it takes over the designated vIP as soon as heartbeat gets connection again - even though the DRBD is running sync (and thus not up to date)



How can I configure heartbeat to perform failback as soon as Server1 again is in sync with Server2 ? (And not before)

Sudden increase in CPU use by Apache, without increase in requests, disk i/o, php/database connections, etc




This morning we saw a step increase in CPU utilization and load on our web server, call it host1. Overall CPU usage went from approximately 100% to 500% (on 16 cores, 32 hyperthreads), and load from < 1 to ~6 average. It then remained at that increased level. Using top, it's clear that the added CPU usage is all by Apache (httpd processes). (We're on Apache 2.4.39, on CentOS 7.6.)



PHP processes and mariadb connections are both unchanged from their baseline levels. Data transferred over the server's network connection is unchanged. Requests served per minute, based on line counts of the server's domlogs are unchanged. There has been no increase in disk utilization, wait time, or service time. Memory usage is also flat.



I checked the Apache error log for the time when the load jumped up, and didn't see anything new, nor did Apache restart at that time.



As a test, I moved all our web traffic from host1 to an effectively identical backup server, host2. Once the traffic was migrated, host1 cpu usage dropped to near zero (a drop of ~400% at that point), while the usage on host2 increased to only ~80%, about the level host1 was running at before the sudden increase. So, whatever changed, it's something to do with that specific server, not with the nature of our web traffic.



I checked the apache configurations on both servers, and as expected, they are identical. Looking at apache status, # of simultaneous connections appears to be roughly double on host1 compared to host2. This is as you would expect given higher load/cpu usage. It's taking longer to serve requests, so we have more simultaneous connections sticking around for the same throughput. Subjectively, it seems like some requests are returning in a normal amount of time on host1, while others are taking significantly longer than usual (seconds rather than the expected milliseconds). That could be a cause or a consequence of the higher load though.




I tried disabling mod_security on host1, and ruled that out as the cause. Next I tried rebooting host1 completely, but after transferring traffic back, the high load persisted. Any idea what else might cause apache on a particular server to suddenly and persistently start using more cpu and taking longer to serve the same volume of requests?



Edit: for what it's worth, both system and user cpu use stepped up proportionally.



Edit 2: Results of perf top:



Samples: 905K of event 'cycles:ppp', Event count (approx.): 111054988919
Overhead Shared Object Symbol
16.69% [kernel] [k] system_call_after_swapgs
11.02% [kernel] [k] sysret_check

5.64% [kernel] [k] copy_user_enhanced_fast_string
3.79% [kernel] [k] fget_light
3.04% [kernel] [k] __audit_syscall_exit
3.01% [kernel] [k] generic_file_aio_read
2.51% [kernel] [k] __audit_syscall_entry
1.78% [kernel] [k] sys_lseek
1.63% [kernel] [k] __radix_tree_lookup
1.45% [kernel] [k] sys_read
1.43% libpthread-2.17.so [.] __pthread_disable_asynccancel
1.32% [kernel] [k] touch_atime

1.28% [kernel] [k] ext4_file_read
1.23% [kernel] [k] radix_tree_descend
1.11% [kernel] [k] mutex_lock
1.08% [kernel] [k] vfs_read
1.04% [kernel] [k] file_read_actor
0.95% libapr-1.so.0.6.5 [.] apr_file_read
0.85% [kernel] [k] do_sync_read
0.84% [kernel] [k] __d_lookup_rcu
0.81% [kernel] [k] __x86_indirect_thunk_rax
0.79% [kernel] [k] fsnotify

0.78% [kernel] [k] generic_segment_checks
0.77% [kernel] [k] __check_object_size
0.74% [kernel] [k] current_kernel_time
0.73% libapr-1.so.0.6.5 [.] apr_file_read_full
0.71% [kernel] [k] put_page
0.70% [kernel] [k] ext4_llseek
0.70% php-fpm [.] execute_ex
0.69% libaprutil-1.so.0.6.1 [.] getpage
0.65% [kernel] [k] _cond_resched
0.64% libaprutil-1.so.0.6.1 [.] read_from

0.59% [kernel] [k] strncpy_from_user
0.59% libpthread-2.17.so [.] llseek
0.57% [kernel] [k] __fsnotify_parent
0.57% [kernel] [k] cleanup_module
0.55% [kernel] [k] rw_verify_area
0.55% [kernel] [k] __find_get_page
0.51% [kernel] [k] auditsys
0.51% [kernel] [k] security_file_permission
0.48% php-fpm [.] _is_numeric_string_ex
0.47% [kernel] [k] unroll_tree_refs

0.47% libapr-1.so.0.6.5 [.] apr_file_seek
0.42% [kernel] [k] generic_file_llseek_size
0.41% [kernel] [k] fput
0.40% php-fpm [.] zend_hash_find
0.35% [kernel] [k] __virt_addr_valid
0.30% [kernel] [k] path_put
0.27% libaprutil-1.so.0.6.1 [.] getnext
0.27% libz.so.1.2.7 [.] 0x0000000000002d11
0.27% [kernel] [k] tracesys
0.27% [unknown] [k] 0x00002af9a2716d7b

0.27% [kernel] [k] lookup_fast
0.25% [kernel] [k] mutex_unlock
0.25% [kernel] [k] kfree
0.24% [kernel] [k] current_fs_time


For comparison, here are the results from our other server, host2, which is handling a comparable amount of web traffic, plus all our databases currently, and isn't experiencing this high load issue:



Samples: 1M of event 'cycles:ppp', Event count (approx.): 104427407206424
Overhead Shared Object Symbol

27.34% [kernel] [k] retint_userspace_restore_args
13.57% php-fpm [.] zend_do_inheritance
7.56% [kernel] [k] handle_mm_fault
7.56% httpd [.] 0x000000000004470e
6.87% libpthread-2.17.so [.] pthread_cond_broadcast@@GLIBC_2.3.2
4.43% [kernel] [k] cpuidle_enter_state
3.31% libc-2.17.so [.] __memmove_ssse3_back
3.31% [unknown] [.] 0x00002b8a4d236777
2.68% [kernel] [k] cap_inode_permission
2.09% libperl.so [.] S_refto

2.09% [unknown] [k] 0x00007f4479518900
1.37% [kernel] [k] free_pages_prepare
1.20% [kernel] [k] hrtimer_interrupt
0.90% [kernel] [k] irq_return
0.89% [kernel] [k] change_pte_range
0.76% httpd [.] ap_find_command
0.69% [unknown] [k] 0x00007fe15a923be8
0.68% [kernel] [k] lookup_fast
0.60% libperl.so [.] Perl_runops_standard
0.60% libperl.so [.] Perl_pp_multideref

0.60% [unknown] [.] 0x00007f227838a777
0.55% [kernel] [k] system_call_after_swapgs
0.46% [unknown] [.] 0x00007f18e7736015
0.45% libc-2.17.so [.] __memcpy_ssse3_back
0.40% mysqld [.] 0x0000000000b643c4
0.40% ld-2.17.so [.] _dl_map_object_deps
0.39% [unknown] [.] 0x00007f81151f761c
0.35% [kernel] [k] kmem_cache_alloc
0.35% [kernel] [k] vma_interval_tree_insert
0.30% [kernel] [k] _raw_spin_lock_irqsave

0.30% libc-2.17.so [.] __readdir_r
0.30% [kernel] [k] tick_do_update_jiffies64
0.30% libpng15.so.15.13.0 [.] 0x000000000001ff7f
0.30% [unknown] [.] 0x00007f2a3ffee13c
0.30% libpthread-2.17.so [.] __ctype_init@plt
0.26% libc-2.17.so [.] _int_malloc
0.26% libc-2.17.so [.] malloc
0.26% libc-2.17.so [.] malloc_consolidate
0.26% [kernel] [k] mem_cgroup_charge_common
0.26% libperl.so [.] Perl_hv_common

0.26% [kernel] [k] pid_revalidate
0.26% libperl.so [.] Perl_sv_eq_flags
0.26% libcairo.so.2.11512.0 [.] 0x000000000004bf43
0.26% libperl.so [.] S_dopoptosub_at
0.26% libcairo.so.2.11512.0 [.] 0x00000000000d059a


host2 is much more variable in terms of the top functions though; this is just one example. host1 (the one with the problem) has a very stable top few entries in the list.



Edit 3: Having tracked the issue down to mod security, I've specifically found it appears to be related to the IP address database, /tmp/ip.pag, growing indefinitely, despite the pruning timeouts we have in place. Clearing this file resolves the high CPU usage without disabling mod security entirely. However it will presumably grow again if we continue using IP based rules, so we're looking into modifying our rules, or may just set up a daily cron to clear out any old IPs in the file.



Answer



First sanity check if the kernel is trying to tell you something. Maybe about the storage system because of the storage stack appearing the samples. Review the output of dmesg and syslog log files.






Your problem host is spending more time in the kernel. Contrast that to the other host where php-fpm and httpd are in the top 5. Most workloads do useful services in user space, so low kernel overhead is good.



Note the time spent in the audit interfaces. And I think fsnotify is used by the audit system as well. Review any audit rules, including file system and system calls. Auditing anything like all reads is very expensive. See the documentation of the auditd package for examples of targeted auditing in a few scenarios.



Lots of detail about what Linux is up to is possible if you profile further. Use perf to count syscalls. Also possible is getting the entire call graph in a flame graph visualization.




Edit: those flame graphs are particularly useful in a high CPU utilization scenario if you have symbols. You can compare to problem stacks in issue reports, and dig further into the specific function that was taking a long time.



Install yum-utils and use this to install symbols: debuginfo-install --enablerepo=base-debuginfo httpd
(It is a convenience script so you don't have to know the -debuginfo postfix convention.)



You found ModSecurity issue Spontaneously high CPU usage #890. I don't actually see stack like that yet on your flame graphs. But if you install debug symbols you can see things that are interactions between APR, the module code, and the OS kernel, beyond just one of those.


linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...