| « décembre 2009 |
| lun. | mar. | mer. | jeu. | ven. | sam. | dim. |
|---|
| | 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | | | |
| | | | | | | |
| Today |

jeudi octobre 08, 2009
CMT, NFS and 10 Gbe
Now that we have Gigabytes/sec class of Network Attached
OpenStorage and
highly threaded
CMT
servers to attach from you figure just connecting the two would be
enough to open the pipes for immediate performance. Well ... almost.
Our openstorage system can deliver great
performance but we often find
limitation on the client side. Now that NAS servers can deliver so much power,
their NAS client can themselve be powerful servers trying to deliver
GB/sec class services to the internet.
CMT servers are great throughput engines for that, however they
deliver the goods when the whole stack is threaded. So in a recent
engagement, my collegue David Lutz found that we needed one tuning at
each of 4 levels in Solaris : IP, TCP, RPC and NFS.
| Service | Tunable |
| IP | ip_soft_ring_cnt |
| TCP | tcp_recv_hiwat |
| RPC | clnt_max_conns |
| NFS | nfs3_max_threads |
| NFS | nfs4_max_threads |
ip_soft_rings_cnt requires tuning up to Solaris 10 update 7.
The default value of 2 is not enough to sustain the high throughput in
a CMT environment. A value of 16 proved beneficial.
In /etc/system :
* To drive 10Gbe in CMT in Solaris 10 update 7 : see blogs.sun.com/roch
set ip_soft_rings_cnt=16
The receive socket buffer size is critical to the TCP connection
performance. The buffer is not preallocated and memory is only
used if and when the application is not reading the data
it has requested. The default at 48K is from the age of 10MB/s Network cards
and 1GB/sec systems. Having a larger value allows the peer to not
throttle it's flow pending the returning TCP ACK. This is specially
critical in high latency environment, urban area networks or other
large fat network but it's also critical in the datacenter to reach a
reasonable portion of the 10Gbe available in today's NIC. It turns out
that NFS connection inherit the TCP default for the system and so it's
interesting to run with a value between 400K and 1MB :
ndd -set /dev/tcp_recv_hiwat 400000
But even with this, a single TCP connection is not enough to extract
the most out of 10Gbe on CMT. And the solaris rpc client will
establish a single connection to any of the server it connects to.
The code underneath is highly threaded but did suffer from a few bugs
when trying to tune that number of connections notably
6696163,
6817942
both of which are fixed in S10 update 8.
With that release, it becomes interesting to tune the number of RPC
connections for instance to 8.
In /etc/system :
* To drive 10Gbe in CMT in Solaris 10 update 8 : see blogs.sun.com/roch
set clnt_max_conns=8
And finally, above the RPC layer, NFS does implement a pool of threads
per mount point to service asynchronous requests. These will be mostly
used in streaming workloads (readahead and writebehind) while other
synchronous requests will be issued within the context of the
application thread. The default number of asynchronous requests is
likely to limit performance in some streaming scenario. So
I would experiment with
In /etc/system :
* To drive 10Gbe in CMT in Solaris 10 update 7 : see blogs.sun.com/roch
set nfs3_max_threads=32
set nfs4_max_threads=32
As usual
YMMV and use
them with the usual circumspection, remember that
tuning
is evil but it's better to know about these factors than being in
the dark and stuck with lower than expected performance.

jeudi septembre 17, 2009
iSCSI unleashed
One of the much anticipated feature of the
2009.Q3 release of the
fishworks OS is a complete rewrite of the iSCSI target implementation
known as Common Multiprotocol SCSI Target or
COMSTAR. The new target code is
an in-kernel implementation that replaces what was previously known as
the iSCSI target deamon, a user-level implementation of iSCSI.
Should we expect huge performance gains from this change ?
You Bet !
But like most performance question, the answer is often : it
depends. The measured performance of a given test is gated by the
weakest link triggered. iSCSI is just one component among many others
that can end up gating performance. If the daemon was not a limiting
factor, then that's your answer.
The target deamon was a userland implementation of iSCSI : some daemon
threads would read data from a storage pool and write data to a socket
or vice versa. Moving to a kernel implementation opens up options to
bypass at least one of the copies and that is being considered as a
future option. But extra copies while undesirable do not necessarily
contribute to the small packet latency or large request throughput;
For small packets requests, the copy is small change compared to the
request handling. For large request throughput the important things is
that the data path establishes a pipelined flow in order to keep every
components busy at all times.
But the way threads interact with one another can be a much greater
factor in delivered performance. And there lies the problem. The old
target deamon suffered from one major flaw in that each and every
iSCSI requests would require multiple trips through a single queue
(shared between every luns) and that queue was being read and written
by 2 specific threads. Those 2 threads would end up fighting for the
same locks. This was compounded by the fact that user level threads
can be put to sleep when they fail to acquire a mutex and that going
to sleep for a user level thread is a costly operation implying a
system call and all the accounting that goes with that.
So while the iSCSI target deamon gave reasonable service for large
request, it was much less scalable in terms of the number IOPS that
can be served and the CPU efficiency in which it could do that. IOPS
being of course a critical metrics for block protocols.
As an illustration of that with 10 client initiators and 10 threads
per initiators (so 100 outstanding request) doing 8K cache-hit reads,
we observed
| Old Target Daemon | Comstar | Improvement |
| 31K IOPS | 85K IOPS | 2.7X |
Moreover the target daemon was consuming 7.6 CPU to service those
31K IOPS while comstar could handle 2.7X more IOPS consuming only 10
cpus, a 2X improvement in iops per cpu efficiency.
On the write side, with a disk pool that had 2 striped write
optimised SSD, comstar gave us 50% more throughput (130 MB/sec vs
88MB/sec) and 60% more cpu efficiency.
Immediatedata
During our testing we noted a few interesting contributor to delivered
performance. The first being the setting of iSCSI
immediatedata
parameter
iSCSIadm(1M). On the
write path, that parameter will cause the initiator iSCSI to send up
to 8K of data along with the initial request packet. While this is a good
idea to do so, we found that for certain sizes of writes, it would
trigger some condition in the zil that caused ZFS to issue more data
than necessary through the logzillas. The problem is well understood
and remediation is underway and we expect to get to a situation in
which keeping the default value of
immediatedata=yes is the best. But
as of today, for those attempting world record data transfer speeds
through logzillas, setting
immediatedata=no and using a 32K or 64K write
size might yield positive result depending on your client OS.
Interrupt Blanking
Interested in low latency request response ? Interestingly, a chunk of
that response time is lost in the obscure setting of network card
drivers. Network cards will often delay pending interrupts in the hope
of coalescing more packets into a single interrupt. The extra
efficiency often results in more throughput at high data rate at the
expense of small packet latency. For 8K request we manage to get 15%
more single threaded IOPS by tweaking one such client side
parameter. Historically such tuning has always been hidden in the
bowel of each drivers and specific to ever client OS so that's too
broad a topic to cover here. But for Solaris clients, the
Crossbow
framework is aiming among other thing to make latency vs throughput decision
much more adaptive to operating condition relaxing the need for per
workload tunings.
WCE Settings
Another important parameter to consider for comstar is the 'write
cache enable' bit. By default all write request to an iSCSI lun needs
to be committed to stable storage as this is what is expected by most
consumers of block storage. That means that each individual write
request to a disk based storage pool will take minimally a disk
rotation or 5ms to 8ms to commit. This also why a write optimised SSD
is quite critical to many iSCSI workloads often yeilding 10X
performance improvements. Without such an SSD, iSCSI performance will
appear quite lackluster particularly for lightly threaded workloads
which more affected by latency characteristics.
One could then feel justified to set the write cache enable bits on
some luns in order to recoup some spunk in their engine. One good news
here is that in the new 2009.Q3 release of fishworks the setting is
now persistent across reboots and reconnection event, fixing a nasty
condition of 2009.Q2. However one should be very careful with this
setting as the end consumer of block storage (exchange, NTFS,
oracle,...) is quite probably operating under an unexpected set of
condition. This setting can lead to application corruption in case
of outage (no risk for the storage internal state).
There is one exception to this caveat and it is ZFS itself. ZFS is
designed to safely and correctly operate on top of devices that have
their write cached enabled. That is because ZFS will flush write
caches whenever application semantics or its own internal consistency
require it. So a ZPOOL created on top of iSCSI luns would be well
justified to set the WCE on the lun to boost performance.
Synchronous write bias
Finally as described in my blog entry about
Synchronous write bias,
we now have to option to bypass the write optimised SSDs for a lun if
the workload it receive is less sensitive to latency. This would be
the case of a highly threaded workload doing large data
transfers. Experimenting with this new property is warranted at this
point.
Synchronous write bias property
With the release of
2009.Q3 release of fishworks along with a new
iSCSI
implemtation we're coming up with
a very significant new feature for managing performance of Oracle
database : the new dataset
Synchronous write bias property or
logbias for short. In a nutshell, this
property takes the default value of
Latency signifying that the
storage should handle synchronous writes in urgency, the historical
default handling. See
Brendan's
comprehensive blog entry on the Separate Intent Log and synchronous writes.
However for datasets holding Oracle
Datafiles,
the
logbias property can be set to
Throughput signifying that the
storage should avoid using log devices acceleration instead trying to
optimize the workload's throughput and efficiency. We definitely
expect to see a good boost to Oracle performance from this feature for
many types of workloads and configs; workloads that generate
10s of MB/sec of DB writer traffic and have no more than 1 logzilla per tray/JBOD.
The property is set in the
Share Properties just above
database recordsize. You might need to unset the
Inherit from
projet checkbox in order to modify the settings on a particular
share:

The
logbias property addresses a peculiar aspect of Oracle workloads :
namely that DB writers are issuing a large number of concurrent
synchronous writes to Oracle datafiles, writes which individually
are not particularly urgent. In contrast to other types of synchronous
writes workloads, the more important metrics for DB Writers is not
about individual latency. The important metric is that the storage
keep up with the
throughput demand in order to have database buffers
always available for recycling. This is unlike redo log
writes which are critically sensitive to latency as they are holding
up individual transactions and thus users.
ZFS and the ZIL
A little background; with ZFS, synchronous writes are managed by the
ZFS Intent Log
ZIL.
Because synchronous writes are typically holding up applications, it's
important to handle those writes with some level of urgency and the
ZIL does an admirable job at that.
In the Openstorage
hybrid storage pool the ZIL itself
is speeded up using low latency write-optimized SSD devices : the
logzillas. Those devices are used to commit a copy of the in-memory
ZIL transaction and retain the data until an upcoming transaction group
commits the in-memory state to the on-disk pooled storage
(
Dynamics of
ZFS,
The
New ZFS write throttle).
So while the ZIL speeds up synchronous writes, logzillas speeds up the
zil. Now SSDs can serve IOPS at a blazing 100μs but also have
their own throughput limits: currently around 110MB/sec per device.
At that throughput, committing, for example, 40K of data will need
minimally 360μs. The more data we can divert away from log devices, the lower the
latency response of those devices will be.
It's interesting to note that other types of raid controllers will be
hostage of their NVRAM and
require, for consistency, that data be
committed through some form of acceleration in order to avoid the
Raid
Write Hole (
Bonwick on Raid-Z). ZFS, however,
does require that data passes through its SSD commit accelerator and
it can manage consistency of commits either using disk
or using
SSDs.
Synchronous write bias : Throughput
With this newfound ability of storage administrators to signify to ZFS
that some datasets will be subject to highly threaded synchronous
writes for which global throughput is more critical than individual
write latency, we can enable a different handling mode. By setting
Logbias=Throughput ZFS is able to divert writes away from
the Logzillas which are then preserved for servicing low latency
sensitive operations (e.g. redo log operations).
- A setting of Synchronous write bias : Throughput for a dataset allows synchronous
writes to files in other datasets to have lower latency
access to SSD log devices.
But that's not all. Data flowing through a
logbias=Throughput
dataset is still served by the ZIL. It turns out that the ZIL has
different internal options in the way it can commit transactions one
of which being tagged WR_INDIRECT. WR_INDIRECT commits issue an
I/O for the modified file record and record a pointer to it in the zil chain.
(see WR_INDIRECT in
zil.c,
zvol.c,
zfs_log.c
).
ZIL transaction of type WR_INDIRECT might use more disk I/Os and
slightly higher latency immediately but less I/Os and less total bytes
during the upcoming transaction group update. Up to this point, the
heuristics that lead to using WR_INDIRECT transactions, were not
triggered by DB writer workloads. But armed with the knowledge that
comes with the new
logbias property, we're now less concerned
about the slight latency increase that WR_INDIRECT can have. So from
efficiency consideration the
logbias=Throughput datasets
are now set to use this mode leading to more leveled latency
distributions of Transactions.
- Synchronous write bias : Throughput is a dataset mode that reduces the number of
I/Os that need to be issued on behalf of this dataset during the regular transaction
group updates leading to more leveled response time.
A reminder that such kind of improvements sometimes can go unnoticed
in sustained benchmarks if the downstream Transaction group destage is
not given enough resources. Make sure you have enough spindles (or
total disk KRPM) to sustain the level of performance you need. A
pool with 2 logzillas and a single JBOD, might have enough SSD
throughput to absorb DB writer workloads without adversely affecting
redo log latency and so would not benefit from the special logbias
settings, however for 1 logzillas per JBOD the situation might be
reversed.
While the DB Record Size property is inherited by files in a dataset and is
immutable, the logbias setting is totally dynamic and can be
toggled on the fly during operations. For instance, during database
creation or some lightly threaded write operations to Datafiles, it's
expected that
logbias=Latency should perform better.
Logbias deployments for Oracle
As of the 2009.Q3 release of fishworks, the current wisdom around
deploying Oracle DB an Openstorage system with SSD acceleration, is to
segregate, at the filesystem/dataset level, but within the single
storage pool, Oracle datafiles, index files and redo Log files. Having
each type of files in different dataset allows better observability
into each one using the great
analytics
tool. But also, each dataset can then be tuned independantly to
deliver the most stable performance characteristics. The most
important parameter to consider is the ZFS internal recordsize used to
manage the files. For Oracle datafiles the established (
ZFS
Best Practice) is to match the recordsize and the DB block size.
For redo log files using default 128K records means that fewer file
updates will be stradling multiple filesystem records. With 128K
records we expect to have fewer transaction needing to wait for redo
log input I/Os leading more leveled latency distribution for
transactions. As for Index files, using smaller blocks of 8K offers
better cacheability feature for both the primary and
secondary caches
(only cache what is used from indexes), but using larger blocks offers
better index-scan performance. Experimenting is in order, depending on
your use case, but an intermediate block size of maybe 32K might also
be considered for mixed usage scenario.
For Oracle datafiles specifically, using the new setting of
Synchronous write bias : Throughput has potential to deliver
more stable performance in general and higher performance for redo log
sensitive workloads.
| Dataset | Recordsize | Logbias |
| Datafiles | 8K | Throughput |
| Redo Logs | 128K(default) | Latency(default) |
| Index | 8K-32K? | Latency(default) |
Following these guidelines yielded a 40% boost in our Transaction
processing testing in which we had 1 logzillas for a 40 disk pool.

vendredi juin 19, 2009
ZFS and OpenStorage things you might have missed
Here are a few things that caught my attention.
First off, a great post showing the scalability of a 7410 with SAS Grid
Computing all the way to 900MB/sec+ of throughput through a single IP
interface.
SAS Grid and OpenStorage 7410
You'd think a CPU benchmark would not be speeded up by filesystem
consideration but think again as you see this detailed study of
ZFS accelerated SPEC CPU
Also keep an eye on MySQL best practice from Neel and his cool
mysql/innodb tools :
MySQL Inno DB best practices,
Inniostat &
MySQL Truss
It quite nice to see that all the engineering effort is really coming together now.
The ZFS we have today has made incredible strides in the last year.

jeudi juin 11, 2009
Compared Performance of Sun 7000 Unified Storage Array Line
The Sun Storage 7410 Unified Storage Array provides high-performance
for NAS environments. Sun's product can be used on a wide variety of
applications. The Sun Storage 7410 Unified Storage Array with a _single_
10 GbE connection delivers linespeed of the 10 GbE.
- The Sun Storage 7410 Unified Storage Array delivers 1 GB/sec throughput performance.
- The Sun Storage 7310 Unified Storage Array delivers over 500
MB/sec on streaming writes for backups and imaging applications.
- The Sun Storage 7410 Unified Storage Array delivers over 22000
of 8K synchronous writes per second combining great DB
performance and ease of deployment of Network Attached Storage
while delivering the economics benefits of inexpensice SATA disks.
- The Sun Storage 7410 Unified Storage Array delivers over 36000
of random 8K reads per second from a 400GB working set for great Mail application
responsiveness. This corresponds to an entreprise of 100000 people
with every employee accessing new data every 3.6 second consolidated
on a single server.
All those numbers characterise a single head of a 7410 clusterable
technology. The 7000 clustering technology stores all data in dual
attached disk trays and no state is shared between cluster heads
(see
Sun 7000 Storage clusters). This
means that an active-active cluster of 2 healthy 7410 will deliver 2X
the performance posted here.
Also note that the performance posted here represent what is acheived
under a very tightly defined constrained
workload (see
Designing 11 Storage metric) and those do not represent the performance limits of the systems. This is testing 1 x 10 GbE port only; each product can have 2 or 4 10 GbE ports, and by running load across multiple ports the server can deliver even higher performance. Achieving maximum performance is a separate exercise done extremely well
by my friend Brendan :
Measurement Method
To measure our performance we used the open source Filebench tool
accessible from SourceForge (
Filebench
on solarisinternals.com). Measuring performance of a NAS storage
is not an easy task. One has to deal with the client side cache which
needs to be bypassed, the synchronisation of multiple clients, the
presence of client side page flushing deamons which can turn asynchronous
workloads into synchronous ones. Because our Storage 7000 line
can have such large caches (up to 128GB of ram and more than 500GB of secondary caches) and we wanted to test disk responses, we
needed to find a backdoor ways to flush those caches on the servers. Read
Amithaba
Filebench
Kit entry on the topic in which he posts a link to the toolkit
used to produce the numbers.
We recently released our first major software update
2000.Q2 and along with that a new lower cost clusterable 96 TB Storage, the
7310.
We report here the compared numbers of a 7310 with the latest software release to those
previously obtained for the 7410, 7210 and 7110
systems each attached to an 18 to 20 client pool over a single 10Gbe interface
with the regular frame ethernet (1500 Bytes). By the way, looking at
brendan's results above, I encourage you to upgrade to use Jumbo Frames
ethernet for even more performance and note that our servers can drive
two 10Gbe at line speed.
Tested Systems and Metrics
The tested setup are :
Sun Storage 7410, 4 x quad core: 16 cores @ 2.3 Ghz AMD.
128GB of host memory.
1 dual port 10Gbe Network Atlas Card. NXGE driver. 1500 MTU
Streaming Tests:
2 x J4400 JBOD, 44 x 500GB SATA drives 7.2K RPM, Mirrored pool,
3 Write optimized 18GB SSD, 2 Read Optimized 100GB SSD.
IOPS tests:
12 x J4400 JBOD, 280 x 500GB SATA drives 7.2K RPM, Mirrored pool,
272 Data drives + 8 spares.
8-Mirrored Write Optimised 18GB SSD, 6 Read Optimized 100GB SSD.
FW OS : ak/generic@2008.11.20,1-0
Sun Storage 7310,2 x quad core: 8 cores @ 2.3 Ghz AMD.
32GB of host memory.
1 dual port 10Gbe Network Atlas Atlas Card (1 port used). NXGE driver. 1500 MTU
4 x J4400 JBOD for a total 92 SATA drives 7.2K RPM
43 mirrored pairs
4 Write Optimised 18GB SSD, 2 Read Optimized 100GB SSD.
FW OS : Q2 2009.04.10.2.0,1-1.15
Sun Storage 7210, 2 x quad core: 8 cores @ 2.3 Ghz AMD
32 GB of host memory.
1 dual port 10Gbe Network Atlas Atlas Card (1 port used). NXGE driver. 1500 MTU
44 x 500 GB SATA drives 7.2K RPM, Mirrored pool,
2 Write Optimised 18 GB SSD.
FW OS : ak/generic@2008.11.20,1-0
Sun Storage 7110, 2 x quad core opteron: 8 cores @ 2.3 Ghz AMD
8 GB of host memory.
1 dual port 10Gbe Network Atlas Atlas Card (1 port used). NXGE driver. 1500 MTU
12 x 146 GB SAS drives, 10K RPM, in 3+1 Raid-Z pool.
FW OS : ak/generic@2008.11.20,1-0
The newly released 7310 was tested with the most recent software revision and that certainly is giving the 7310 an edge over it's peers.
The 7410 on the other hand was measured here managing a much large contingent of storage, including mirrored Logzillas and 3 times as many JBODs and that is
expected to account for some of the performance delta being observed.
| Metrics |
Short Name |
| 1 thread per client streaming cached reads | Stream Read light |
| 1 thread per client streaming cold cache reads | Cold Stream Read light |
| 10 threads per client streaming cached reads | Stream Read |
| 20 threads per client streaming cold cached reads | Cold Stream Read |
| 1 thread per client streaming write | Stream Write light |
| 20 threads per client streaming write | Stream Write |
| 128 threads per client 8k synchronous writes | Sync write |
| 128 threads per client 8k random read | Random Read |
| 20 threads per client 8k random read on cold caches | Cold Random Read |
| 8 threads per client 8k small file create IOPS | Filecreate |
There are 6 read tests, 2 writes test and 1 synchronous write test
which overwrites it's data files as a database would. A final
filecreate test complete the metrics. Test executes against 20GB
working set _per client_ times 18 to 20 clients. There are 4 sets used
in total running over independent shares for a total of 80GB per
client. So before actual runs at taken, we create all working sets
or 1.6 TB of precreated data. Then before each run, we clear all
caches on the clients and server.
In each of the 3 groups of 2 read tests, the first one benefits from
no caching at all and the throughput delivered to the client over the
network is observed to come from disk. The test runs for N seconds
priming data in the Storage caches. A second run (
non-cold) is
then started after clearing the client side caches. Those test will
see the 100% of the data delivered over the network link but not all
of it is coming off the disks. Streaming test will race through the
cached data and then finish off reading from disks. The random read
test can also benefit from increasing cached responses as the test
progresses. The exact caching characteristic of a 7000 lines will
depend on a large number of parameters including your application
access pattern. Numbers here reflect the performance of fully
randomized test over 20GB per client x 20 clients or a 400GB working
set. Upcoming studies will include more data (showing even higher
performance) for workloads with higher cache hit ratio than those used
here.
In a Storage 7000 server, disks are grouped together in one pool and
then individual Shares are creates. Each share has access to all disk
resource subject to quota (a minimum) and reservation (a maximum) that
might be set. One important setup parameter associated with each share
is the DB record size. It is generally better for IOPS test to use 8K
records and for streaming test to use 128K records. The recordsize can
be dynamically set based on expected usage.
The tests shown here were obtained with NFSv4 the default for Solaris clients (NFSv3 is expected to
come out slightly better). The
clients were running Solaris 10, with tuned tcp_recv_hiwat of 400K and
dopageflush=0 to prevent buffered writes from being converted into
synchronous writes.
Compared Results of the 7000 Storage Line
| NFSv4 Test |
7410 Head Mirrored Pool |
7310 Head Mirrored Pool |
7210 Head Mirrored Pool |
7110 Head 3+1 Raid-Z |
| Throughput | | | | |
| Cold Stream Read light | 915 MB/sec | 685 MB/sec | 719 MB/sec | 378 MB/sec |
| Stream Read light | 1074 MB/sec | 751 MB/sec | 894 MB/sec | 416 MB/sec |
| Cold Stream Read | 959 MB/sec | 598 MB/sec | 752 MB/sec | 329 MB/sec |
| Stream Read | 1030 MB/sec | 620 MB/sec | 792 MB/sec | 386 MB/sec |
| Stream Write light | 480 MB/sec | 507 MB/sec | 490 MB/sec | 226 MB/sec |
| Stream Write | 447 MB/sec | 526 MB/sec | 481 MB/sec | 224 MB/sec |
| IOPS | | | | |
| Sync write | 22383 IOPS | 8527 IOPS | 10184 IOPS | 1179 IOPS |
| Filecreate | 5162 IOPS | 4909 IOPS | 4613 IOPS | 162 IOPS |
| Cold Random Read | 28559 IOPS | 5686 IOPS | 4006 IOPS | 1043 IOPS |
| Random Read | 36478 IOPS | 7107 IOPS | 4584 IOPS | 1486 IOPS |
| Per Spindle IOPS | 272 Spindles | 86 Spindles | 44 Spindles | 12 Spindles |
|---|
| Cold Random Read | 104 IOPS | 76 IOPS | 91 IOPS | 86 IOPS |
| Random Read | 134 IOPS | 94 IOPS | 104 IOPS | 123 IOPS |
Analysis
The data shows that the entire Sun Storage 7000 line are throughput
workhorse delivering 10 Gbps level NAS services per cluster head
nodes, using a single Network Interface and single IP address for easy
integration into your existing network.
As with other storage technology write streaming performance require
more involvement from the storage controller and this leads to about
50% less write throughput compared to read throughput.
The use of write optimized SSD in the 7410, 7310 and 7220 also give
this storage very high synchronous write capabilities. This is one of
the most interesting result as it maps to database performance. The ability to
sustain 24000 O_DSYNC writes at 192MB/sec of synchronized user data
using only 48 inexpensive sata disks and 3 write optimized SSD is one
of the many great performance characteristics of this novel storage
system.
Random Read test generally map directly to individual disk
capabilities and is a measure of total disk rotations. The cold runs
shows that all our platforms are delivering data at the expected 100
IOPS per spindle for those SATA disks. Recall that our offering is
based on the economical energy efficient 7.2 RPM disk technology. For
cold random reads, a mirrored pair of 2 x 7.2K RPM offers the same
total disk rotation (and IOPS) as expensive and power hungry 15 K
RPM disks but in a much more economical package.
Moreover the difference between the warm and cold random read runs is
showing that the Hybrid Storage Pool (HSP) is providing a 30% boost
even on this workload that addresses randomly 400GB working set on
128GB of controller cache. The effective boost from the HSP can be
much greater depending on the cacheability of workloads.
If we consider an organisation in which the avg mail message is 8K
in size, our results show that we could consolidate 100000 employees on
a single 7410 storage where each employee is accessing new data every
3.6 seconds with 70ms response time.
Messaging system are also big consumer of file creations, I've shown
in the past how efficient ZFS can be at creating small files
(
Need Inodes ?). For the NFS protocol,
file creation is a straining workload but the 7000 storage line comes
out not too bad with more than 5000 filecreates per second per storage
controller.
Conclusion
Performance Can never be summerised with a few numbers and we have
just begun to scratch the surface here. The numbers presented here
along with the disruptive pricing of the Hybrid Storage Pool will, I
hope, go a long way to show the incredible power of the Open
Storage architecture being proposed. And keep in mind that this
performance is achievable using less expensive, less power hungry SATA
drives and that every data services : NFS, CIFS, iSCSI, ftp, HTTP etc.
offered by our Sun Storage 7000 servers are available at 0 additional
software cost to you.
Disclosure Statement:
Sun Microsystem generated results using filebench. Results reported 11/10/08 and
26/05/2009 Analysis done on June 6 2009.

mercredi mai 27, 2009
Free Beer and Free Deep Dive
For those lucky enough to be in the Bay area next week, I just heard there will be free unlimited beer and free access to the technical deep dives at the Community One event at the Moscone Center and Intercontinental Hotel nearby (and I'm only lying about one of the free thingy).
The program looks great with lots of star speakers on both days, so while free is cool, don't overlook the June 1st program as well.
Lucky you.

mardi mars 03, 2009
Performance of the Hybrid Storage Pool
Hope to be able to keep your attention for 30 minutes of impromptu conversation about OpenStorage performance.
At the end of the piece, I show my geeky capture/replay technology.

vendredi février 13, 2009
Need Inodes ?
It seems that some old school filesystem still need to statically allocate inodes to hold pointers to individual files. Normally this should not cause too much problems as default settings account for an average filesize of
32K. Or will it ?
If the avg filesize you need to store on the filesystem is much smaller than this, they you are likely to eventually run out of inodes even if the space consumed on the storage is far from exhausted.
In ZFS inodes are allocated on demand and so the question came up, how many files can I store onto a piece of storage. I managed to scrape up an old disk of 33GB, created a pool and wanted to see how many 1K files I could store on that storage.
ZFS stores files with the smallest number of sectors possible and so 2 sectors was enough to store the data. Then of course one needs to also store some amount of metadata, indirect pointer, directory entries etc to complete the story. There I didn't know what to expect. My program would create 1000 files per directory. Max depth level is 2, nothing sophisticated attempted here.
So I let my program run for a while and eventually interrupted it at 86% of disk capacity :
Filesystem size used avail capacity Mounted on
space 33G 27G 6.5G 81% /space
Then I counted the files.
#ptime find /space/create | wc
real 51:26.697
user 1:16.596
sys 25:27.416
23823805 23823805 1405247330
So 23.8M files consuming 27GB of data. Basically less than 1.2K of used disk space per KB of files. A legacy type filesystem that would allocate one inode per 32K would have run out of space after a meager 1M files but ZFS managed to store 23X more on the disk without any tuning.
The find command here is mostly gated on fstat performance and we see here that we did the 23.8M fstat in 3060 seconds or 7777 fstat per second.
But here is the best part : And how long did it take to create all those files ?
real 1:09:20.558
user 9:20.236
sys 2:52:53.624
This is hard to believe but it took about 1 hour for 23.8 million files.This is on a single direct attach drive
3. c1t3d0 <FUJITSU-MAP3367N SUN36G-0401-33.92GB>
ZFS created on average 5721 files per second. Now obviously such a drive cannot do 5721 IOPS but with ZFS it
didn't need to. File create is actually more of a cpu benchmark because the application is interacting with host cache. It's the task of the filesystem to then create the files on disk in the background. With ZFS, the combination of the Allocated on Write policy and the sophisticated I/O aggregation in the I/O scheduler (
dynamics) means that the I/O for multiple independant file create can be coalesced. Using dtrace I counted the number of IO required and filecreates per minutes, typical samples show more than 200K files created per minutes using about 3000 IO per minutes or 3300 files per second using a mere 50 IOPS !!!
Per Minute
Sample Create IOs
#1 214643 2856
#2 215409 3342
#3 212797 2917
#4 211545 2999
Finally with all these files, is scrubbing a problem ? It took 1h34m to actually scrub that many files at a pace of 4200 scrubbed files per second. No sweat.
pool: space
state: ONLINE
scrub: scrub completed after 1h34m with 0 errors on Wed Feb 11 12:17:20 2009
If you need to create, store and otherwise manipulate lots of small files efficiently, ZFS has got to be you
filesystem of choice for you.

lundi décembre 15, 2008
Decoding Bonnie++
I've been studying the popular Bonnie++ load generator to see if it
was a suitable benchmark to use with Network attached storage such as
Sun Storage 7000 line.
At this stage I've looked at the single client runs, and it doesn't appear
that Bonnie++ is an appropriate tool in this environment because
as we'll see here, for many of the tests, it either stresses the networking environment
or the strength of client side cpu.
The first interesting thing to note is that Bonnie will work
on a data set that is double the client's memory. This does address
some of the client side caching concern one could otherwise have. In a
NAS environment the amount of memory present on the server is not
considered by a default bonnie++ run. My client had 4GB leading to a
working set was then 8GB while the server had 128GB of memory.
The Bonnie++'s output looks like :
Writing with putc()...done
Writing intelligently...done
Rewriting...done
Reading with getc()...done
Reading intelligently...done
start 'em...done...done...done...
Create files in sequential order...done.
Stat files in sequential order...done.
Delete files in sequential order...done.
Create files in random order...done.
Stat files in random order...done.
Delete files in random order...done.
Version 1.03d ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
v2c01 8G 81160 92 109588 38 89987 67 69763 88 113613 36 2636 67
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 687 10 +++++ +++ 1517 9 647 10 +++++ +++ 1569 8
v2c01,8G,81160,92,109588,38,89987,67,69763,88,113613,36,2635.7,67,16,687,10,+++++,+++,1517,9,647,10,+++++,+++,1569,8
Method
I have used a combination of Solaris truss(1), reading
Bonnie++ code, looking at AmberRoad's
Analytics
data , as well as a custom Bonnie
d-script in
order to understand how each test triggered system calls on the client
and how those translated into a NAS server load. In the d-script, I
characterise the system calls by the average elapse time as well as by
the time spent waiting for a response from the NAS server. The time
spent waiting is the operational latency that one should be interested
in when characterising a NAS, while the additional time relates to the
client CPU strength along with the client NFS implementation. Here is
what I found trying to explain how performant each test was.
Writing with putc()
So easy enough, that test creates a file using single character putc stdio library
call.
This test is clearly a client CPU test with most of the time spent
in user space running putc(). Every 8192 putc, stdio library will
issue a
write(2) system call. That syscall is still a client CPU test
since the data is absorbed on the client cache. What we test here is
the client single CPU performance and the client NFS implementation.
On a 2 CPU/ 4GB V20z running Solaris, we observed on the server using
analytics a network transfer rate of 87 MB/sec.
Results : 87 MB/sec of writes. Limited by single CPU speed.
Writing intelligently...done
Here it's more clever since it writes a file using sequential 8K write
system calls.
In this test the CPU is much relieved. So here the application is
running 8K write system call to client NFS. This is absorbed by memory
on the client. With an Opensolaris client, no over the wire request is
sent for such an 8K write. However after 4 such 8K writes we reach the
natural 32K chunk advertised by the server and that will cause the
client to asynchronously issue a write request to the server. The
asynchronous nature means that this will not cause the application to
wait for the response and the test will keep going on CPU. The process
will now race ahead generating more 8K writes and 32K asynchronous NFS
requests. If we manage to generate such request at a greater rate than
responses, we will consume all allocated aysnchronous threads. On
Solaris this maps to nfs4_max_threads (8) threads. When all 8
asynchronous threads are waiting for a response, then the application
will finally block waiting for a previously issued request to get a
response and free an async thread.
Since generating 8K write systems to fill the client cache is faster
than the network connection between the client and the server we will
eventually reach this point. The steady state of this test is that
Bonnie++ is waiting for data to transfer to the server. This happens
at the speed of a single NFS connection which for us saturated the
1Gbps link we had. We observed 113MB/sec which is network line rate
considering protocol overheads.
To get more through on this test, one could use Jumbo Frame ethernet
instead of the 1500 Byte default frame size used as this would reduce the protocol overhead
slightly. One could also configure the server and client to use
10Gbps ethernet links.
One could also use LACP link aggregation of 1Gbps network ports to
increase the throughput. LACP increases throughput of multiple network
connections but not single socket protocol. By default a Solaris
client will establish a single connection (clnt_max_conns = 1) to a
server (1 connections per target IP). So using multiple aggregated
links _and_ tuning clnt_max_conns could yield extra throughput here.
Using single connection one could use a faster network between client
and server links to reach additional throughput.
More commonly, we expect to saturate the client 1Gbps connectivity
here, not much of a stress for a Sun Storage 7000 server.
Results : 113 MB/sec of writes. Network limited.
Rewriting...done
This gets a little interesting. It actually reads 8K, lseek back to
the start of the block, overwrites the 8K with new data and loops.
So here we read, lseek back, overwrite . For the NFS protocol lseek is
a noop since every over the wire write is tagged with the target
offset. In this test we are effectively stream reading the file from
the server and stream writing the file back to the server. The stream
write behavior will be much like the previous test. We never need to
block the process unless we consume all 8 asynchronous threads.
Similarly 8K sequential reads will be recognised by our client NFS as
streaming access which will deploy asynchronous readahead requests. We
will use 4 (nfs4_nra) request for 32K blocks ahead of the point being
currently read. What we observed here was that of 88 second of elapse
time, 15 was spent in write and 20 in reads. However a small portion
of that was spent waiting for response. It was mostly all spent on CPU
time to interact with the client NFS. This implies that readhead and
asynchronous writeback was behaving without becoming bottlenecks. The
Bonnie++ process took 50 sec of the 88 sec and a big chunk of this, 27
sec, was spent waiting off cpu. I struggle somewhat in this
interpretation but I do know from the Analytics data on the server
that the network is seeing 100 MB/sec of data flowing in each
direction. This must also be close to network saturation. The wait
time attributed to Bonnie++ in this test seems be related to kernel
preemption. As Bonnie++ is coming out of its system calls we see such
events in dtrace.
unix`swtch+0x17f
unix`preempt+0xda
genunix`post_syscall+0x59e
genunix`syscall_exit+0x59
unix`0xfffffffffb800f06
17570
This must be to service the kernel threads of higher priority, likely
the asynchronous threads being spawned by the reads and writes.
This test is then a stress test of bidirectional flow of 32K data
transfers. Just like the previous test, to improve the numbers one
would need to improve the network connection throughput between the
client and server. It also potentially could then benefit from faster
and more client CPUs.
Results : 100MB/sec in each direction, network limited.
Reading with getc()...done
Reads the file one character at a time.
Back to a test of the client CPU much like the first one.
We see that the readahead are working great since little time is spent
waiting (0.4 of 114 seconds). Given that this test does 1 million
reads in 114 seconds, the average latency could be evaluated to be 114
usec.
Results : 73MB/sec, single CPU limited on the client.
Reading intelligently...done
start 'em...done...done...done...
Reads with 8k system calls, sequential.
This test seems to be using 3 spawned bonnie process to read files.
The reads are of size 8K and we needed 1M of them to read our 8GB
working set. We observed with analytics no I/O done on the server
since it had 128GB of cache available to it. The network on the other
hand is saturated at 118 MB/sec.
The dtrace script shows that the 1M read calls collectively spend 64
seconds waiting (most of that NFS response). So that implies a 64 usec
read response time for this sequential workload.
Results : 118MB/sec, limited by Network environment.
start 'em...done...done...done...
Here is seems that Bonnie starts 3 helper processes
used to read the files in the "Reading Intelligently" test.
Create files in sequential order...done.
Here we see 16K files being created (with
creat(2)) then closed.
This test will create and close 16K files and took 22 seconds in our
environment. 19 seconds were used for the creates, 17.5 waiting for
responses. That means a 1ms response time for file creates. The test
seems single threaded. Using analytics we observe 13500 NFS ops per
second to handle those file create. We do see some activity on the
Write bias SSD although very modest at 2.64MB /sec. Given that the
test is single threaded we can't estimate if this metric is
representative of the NAS server capability. More likely this is
representative the single thread capability of the whole environment
made of : client CPU, client NFS implementation, client network driver
and configuration, network envinronment including switches, and the
NAS server.
Results : 744 filecreate per second per thread. Limited by operational latency.
Here is the analytics view captured for the this tests and the
following 5 tests.
Stat files in sequential order...done.
Test was too elusive possibly working against cached stat information.
Delete files in sequential order...done.
Here we
unlink(2) the 16K files.
Here we call the unlink system call for the 16K files. The run takes
10.294 seconds showing a 1591 unlink per second. Each call goes
off cpu, waiting for a server response for 600 usec.
Much like the create file test above, while we get information about
the single threaded unlink time present in the environment it's
obviously not representative of the server's capabilities.'
Results : 1591 unlink per second per thread, Limited by operational latency.
Create files in random order...done.
We recreate 16K files, closing each one but also running a stat()
system call on each.
Stat files in random order...done.
Elusive as above.
Delete files in random order...done.
We remove the 16K files.
I could not discern in the "random order" test any meaninful
differences to the sequential order ones.
Analytics screenshot of Bonnie++ run
Here is the full screen shot from analytics including Disk and CPU
data
The takeway here is that single instance bonnie++ does not generally
stress one Sun Storage 7000 NAS server but will stress the client CPU
and 1Gbps network connectivity. There is no multi-client support in
Bonnie++ (that I could find).
One can certainly start multiple clients simultaneously, but since the
different tests would not be synchronized the output of bonnie++ would
be very questionable. Bonnie++ does have a multi-instance
synchronisation mode that is based on semaphore which will only work if
all instances are running within the same OS environment.
So in a multi client test, Only the total elapsed time would be of
interest here and that would be dominated by the streaming performance
as each client would read and write its working set 3 times over the
wire. Filecreate and unlink times would also contribute to the total
elapsed time of such a test.
For a single node multi-instance bonnie++ run, one would need to have
a large client, with at least 16 x 2Ghz CPUS, and about 10Gbps worth
of network capabilities in order to properly test one Sun Storage 7410
server. Otherwise, Bonnie++ is more likely to show client and network
limits, not server ones. As for unlink capabilities, the topic is a
pretty complex and important one that certainly cannot be captured
with simple commands. The interaction with snapshots and the I/O load
generated on the server during large unlink storms needs to be studied
carefully in order to understand the competitive merits of different
solutions.
In Summary, here is what governs the performance of the
individual Bonnie++ tests :
| Writing with putc()... | 87 MB/sec | Limited by client's single CPU speed |
| Writing intelligently... | 113 MB/sec | Limited
by Network conditions |
| Rewriting... | 100MB/sec | Limited by Network conditions |
| Reading with getc()... | 73MB/sec | Limited by
client's single CPU speed |
| Reading intelligently... | 118MB/sec | Limited
by Network conditions |
| start 'em...done...done...done... |
| Create files in sequential order... | 744 create/s | Limited by operational latency |
| Stat files in sequential order... | not observable |
| Delete files in sequential order... | 1591 unlink/s | Limited by operational latency |
| Create files in random order... | same as sequential |
| Stat files in random order... | same as sequential |
| Delete files in random order... | same as sequential |
So Bonnie++ won't tell you much about our server's
capabilities. Unfortunately, the clustered mode of Bonnie++ won't coordinate
multiple clients systems and so cannot be used to stress a server.
Bonnie++ could be used to stress a NAS server using a single large
multi-core client with very strong networking capabilities.
In the end though I don't expect to learn much about our servers over
and above what is already known. For that please check out our links here :
Low
Level Performance of Sun Storage
Analyzing
the Sun Storage 7000
Designing
Performance Metrics...
Sun
Storage 7xxx Performance Invariants
Here is the
bonnie.d
d-script used
and the output generated
bonnie.out.

lundi novembre 10, 2008
Blogfest : Performance and the Hybrid Storage Pool
Today Sun is announcing a new line of
Unified
Storage designed by a core of the most brilliant engineers . For
starters Mike Shapiro provides a great introduction into this product,
the new economics behind it and the killer App in
Sun
Storage 7000.
The killer App is of course Bryan Cantrill's brainchild, the already
famous
Analytics.
As a performance engineer, it's been a great thrill to have given this
tool an early test drive. Working a full 1 ocean's (the atlantic) + 1
continent (the USA) away from my system running Analytics I was
skeptical at first that I would be visualizing in real time all that
information : the NFS/CIFS ops, the disk ops, the CPU load and network
throughput, per client, per disk, per file ARE YOU CRAZY ! All that
information available IN REAL TIME; I just have to say a big thank you
to the team that made it possible. I can't wait to see our customer
put this to productive use.
Also check out Adam Levanthal's great description of HSP the
Hybrid Storage Pool and read my own perspective on this topic
ZFS as a
Network Attach Storage Controller.
Lest we forget the immense contribution of the boundless Energy bubble
that is Brendan Gregg; the man that braught DTracetoolkit to the
semi-geek; he must be jumping with excitement as we now see the power
of DTrace delivered to each and every system administrator.
He talks here about the
Status
Dashboard. And Brendan's contribution does not stop here, he is
also the parent of this wonderful component of the
HSP known
as the L2ARC which is how the readzillas become activated. See his own
previous work on the
L2ARC along with
Jing Zhang more recent
studies. Quality assurance people don't often get into the spotlight but check out
Tim Foster 's post on how he tortured the zpool code
adding and removing l2 arc devices from pools :
For myself, it's been very exciting to be able to see performance
improvement ideas get turned into product improvements from weeks to
weeks. Those interested should read how our group influenced the product that
is shipping today, see
Alan Chiu
and my own
Delivering Performance Improvements.
Such a product has a strong Price/Performance appeal and given that we
fundamentally did not think that there where public benchmarks that
captured our value proposition, we had to come up with a
third millenium
participative ways to talk about performance. Check out how we
designed our
Metrics
or maybe go straight to our numbers obtained by
Amitabha
Banerjee a concise entry backed up by immense, intense and
carefull data gathering effort in the last few weeks. bmseer is putting his own light
on the
low level data (data to be updated with numbers from a grander config).
I've also posted here a few performance guiding lights to be used
thinking about this product; I call them
Performance
Invariants. So further numbers can be found here about
raid rebuild times.
On the application side, we have the great work of Sean (Hsianglung
Wu) and Arini Balakrishnan showing how a 7210 can deliver
> 5000 concurrent video streams at an aggregate of,
you're kidding, :
WOW ZA 750MB/sec.
More Details on how this was acheived in
cdnperf.
Jignesh Shaw shows step by step instructions setting up
PostgreSQL over iSCSI.
See our Vice President, Solaris Data, Availability, Scalability &
HPC Bob Porras trying to tame this beast into a
nutshell
and pointing out code bits reminding everyone of the value of the
OpenStorage proposition.
See also what bmseer has to say on
Web
2.0 Consolidation and get from Marcus Heckel a walkthrough of
setting up
Olio
Web 2.0 kit with nice Analytics performance screenshots. Also get
the ISV reaction (a bit later) from
Georg Edelmann. Ryan Pratt reports on
Windows Server 2003 WHQL certification of the Sun Storage 7000 line.
And this just in : Data about what to expect from a
Database perspective.
We can talk all we want about performance but as Josh Simons points out,
these babies are available to you for your own
try and buy.
Or check out how you could be running the appliance within the next hour really :
Sun Storage 7000 in VMware.
It seems I am in competition with another less verbose
aggregator
Finally capture the whole stream of related posting to
Sun Storage 7000
Delivering Performance Improvements to Sun Storage 7000
I describe here the effort I spearheaded studying the performance
characteristics of the OpenStorage platform and the ways in which our
team of engineers delivered real out of the box improvements to the
product that is shipping today.
One of the Joy of working on the OpenStorage NAS appliance was
that solutions we found to performance issues could be immediately
transposed into changes to the appliance without further process.
The first big wins
We initially stumble on 2 major issues, one for NFS synchronous writes
and one for the CIFS protocol in general. The NFS problem was a subtle
one involving the distinction of O_SYNC vs O_DSYNC writes in the ZFS
intent log and was impacting our threaded synchronous writes test by
up to a 20X factor. Fortunately I had an history of studying that part
of the code and could quickly identify the problem and suggest a
fix. This was tracked as
6683293: concurrent O_DSYNC writes to a
fileset can be much improved over NFS.
The following week, turning to CIFS studies, we were seeing great
scalability limitation in the code. Here again I was fortunate to be
the first one to hit this. The problem was that to manage CIFS request
the kernel code was using simple kernel allocations that could
accommodate the largest possible request. Such large allocations and
deallocations causes what is known as a storm of TLB shootdown
cross-calls limiting scalability.
Incredibly though after implementing the trivial fix, I found that the
rest of the CIFS server was beautifully scalable code with no other
barriers. So in one quick and simple fix (using kmem caches) I could
demonstrate a great scalability improvements to CIFS. This was
tracked as
6686647
: smbsrv scalability impacted by memory
Since those 2 protocol problems were identified early on, I must say
that no serious protocol performance problems have come up. While we
can always find incremental improvements to any given test, our
current implementation has held up to our testing so far.
In the next phase of the project, we did a lot of work on improving
network efficiency at high data rate. In order to deliver the
throughput that the server is capable of, we must use 10Gbps network
interface and the one available on the NAS platforms are based on the
Neptune networking interface running the nxge driver.
Network Setup
I collaborated on this with
Alan Chiu that already new a
lot about this network card and driver tunables and so we quickly
could hash out the issues. We had to decide for a proper out of the
box setup involving
- how many MSI-X interrupts to use
- whether to use networking soft rings or not
- what bcopy threshold to use in the driver as opposed to
binding dma.
- Whether to use or not the new Large Segment Offload (LSO)
technique for transmits.
We new basically where we wanted to go here. We wanted many interrupts
on receive side so as to not overload any CPU and avoid the use of
layered softrings which reduces efficiency. A low bcopy threshold so
that dma binding be used more frequently as the default value was too
high for this x64 based platform.
And LSO was providing a nice boost to efficiency. That got us to some
proper efficiency level.
However we noticed that under stress and high number of connections
our efficiency would drop by 2 or 3 X. After much head scratching we
rooted this to the use of too many TX dma channels. It turns out that
with this driver and architecture using a few channels leads to more
stickyness in the scheduling and much much greater efficiency. We
settled on 2 tx rings as a good compromise. That got us to a level
of 8-10 cpu cycles per byte transfered in network code (more on
Performance
Invariants).
Interrupt Blanking
Studying a Opensource alternative controller, we also found that on 1
of 14 metrics we where slower. That was rooted in the interrupt
blanking parameter that NIC use to gain efficiency. What we found here
was that by reducing our blanking to a small value we could leapfrog
the competition (from 2X worse to 2X better) on this test while
preserving our general network efficiency. We were then on par or
better for every one of the 14 tests.
Media Streaming
When we ran thousand or 1 Mb/s media streams from our systems we
quickly found that the file level software prefetching was hurting us.
So we initially disabled the code in our lab to run our media studies
but at the end of the project we had to find an out of the box setup
that could preserve our Media result without impairing maximum read
streaming. At some point we realized that what we were hitting
6469558:
ZFS prefetch needs to be more aware of memory pressure. It turns out
that the internals of zfetch code is setup to manage 8 concurrent
streams per file and can readahead up to 256 blocks or records : in
this case 128K. So when we realized that with 1000s of streams we
could readahead ourself out of memory, we knew what we needed to
do. We decided on setting up 2 streams per file reading ahead up to 16
blocks and that seems quite sufficient to retain our media serving
throughput while keeping so prefetching capabilities. I note here also
is that NFS client code will themselve recognize streaming and issue
their own readahead. The backend code is then reading ahead of client
readahead requests. So we kind of where getting
ahead of
ourselves here. Read more about it @
cndperf
To slog or not to slog
One of the innovative aspect of this Openstorage server is the use of
read and write optimized solid state devices; see for instance
The Value of Solid State Devices.
Those SSD are beautiful devices designed to help
latency but not throughput. A massive commit is actually better handled by
regular storage not ssd. It turns out that it was actually dead easy
to instruct the ZIL to recognize massive commits and divert it's block
allocation strategy away from the SSD toward the common pool of
disks. We see two benefits here, the massive commits will sped up
(preventing the SSD from becoming the bottleneck) but more importantly
the SSD will now be available as low latency devices to handle
workloads that rely on low latency synchronous operations. One should
note here that the ZIL is a "per filesystem" construct and so while a
filesystem might be working on a large commit another filesystem from
the same pool might still be running a series of small transaction and
benefit from the write optimized SSD.
In a similar way, when we first tested the read-optimized ssds , we quickly
saw that streamed data would install in this caching layer and that it
could slow down the processing later. Again the beauty of working on
an appliance and closely with developers meant that the following
build, those problems had been solved.
Transaction Group Time
ZFS operates by issuing regular transaction groups in which
modifications since last transaction group are recorded on disk and
the ueberblock is updated. This used to be done at a 5 second interval
but with the recent improvement to the
write
throttling code this became a 30 second interval (on light
workloads) which aims to not generate more than 5 seconds of I/O per
transaction groups. Using 5 seconds of I/O per txg was used to
maximize the ratio of data to metadata in each txg, delivering more
application throughput. Now these Storage 7000 servers will typically
have lots of I/O capability on the storage side and the data/metadata
is not as much a concern as for a small JBOD storage. What we found
was that we could reduce the the target of 5 second of I/O down to 1
while still preserving good throughput. Having this smaller value
smoothed out operation.
IT JUST WORKS
Well that is certainly the goal. In my group, we spent the
last year performance testing these OpenStorage systems finding and
fixing bugs, suggesting code improvements, and looking for better
compromise for common tunables. At this point, we're happy with the
state of the systems particularly for mirrored configuration with
write optimized SSD accelerators. Our code is based on a recent
OpenSolaris (from august) that already has a lot of improvements over
Solaris 10 particularly for ZFS, to which we've added specific
improvements relevant to NAS storage. We think these systems will at
times deliver great performance (see Amithaba's
results
) but almost always shine in the price performance categories.
Sun Storage 7000 Performance invariants
I see many reports about running campains of test measuring
performance over a test matrix. One problem with this approach is of
course the
Matrix.
That matrix never big enough for the consumer of the information ("can
you run this instead ?").
A more useful approach is to think in terms of performance
invariants. We all know that 7.2K RPM disk drive can do 150-200 IOPS
as an invariant and disks will have throughput limit such as
80MB/sec. Thinking in terms of those invariant helps in extrapolating
performance data (with caution) and observing breakdowns in invariant
is often a sign that something else needs to be root caused.
So using 11 metrics and our Performance engineering effort what can be
our guiding invariants ? Bearing in mind that it is expected that
those are rough estimate. For real measured numbers check out Amitabha
Banerjee's excellent post on
Analyzing the Sun Storage 7000.
Streaming : 1 GB/s on server and 110 MB/sec on client
For read Streaming wise, we're observing that 1GB/s is somewhat our
guiding number for read streaming . This can be acheived with fairly
small number of client and threads but will be easier to reach if the
data is prestaged in server caches. A client normally running 1Gbe
network cards is able to extract 110 MB/sec rather easily. Read
streaming will be easier to acheived with the larger 128K records
probably due to the lesser CPU demand. While our results are with
regular 1500 Bytes ethernet frames, using jumbo frame will also make
this limit easier to reach or even break. For a mirrored pool, data
needs to be sent twice to the storage and we see a reduction of about
50% for write streaming workloads.
Random Read I/Os per second : 150 random read IOPS per mirrored disks
This is probably a good guiding light also. When going to disks that
will be a reasonable expectation. But here caching can radically
change this. Since we can configure up to 128GB of host ram and 4
times that much of secondary caches, there are opportunity to break
this barrier. But when going to spindles that needs to be kept under
consideration. We also know that Raid-z spreads records to all
disks. So the 150 IOPS limit basically applies to
raid-z groups. Do
plan to have many groups to service random reads.
Random Read I/Os per second using SSDs : 3100 Read IOPS per Read Optimized SSD
In some instances, data after eviction from main memory will be kept
in secondary caches. Small files and tuned recordsize filesystem are
good target workload for this. Those read-optimized SSD can restitute this
data at a rate of 3100 IOPS
L2 ARC). More
importantly so it can do so at much reduced latency meaning that
lightly threaded workloads will be able to acheive high throughput.
Synchronous writes per second : 5000-9000 Synchronous write per Write Optimized SSD
Synchronous writes can be generated by a O_DSYNC write (database) or
just as part of the NFS protocol (such as the tar extract :
open,write,close workloads). Those will reach the NAS server and be
coalesced in a single transaction with the separate intent log. Those
SSD devices are great latency accelerators but are still devices with
a max throughput of around 110 MB/sec. However our code actually
detects when the SSD devices become the bottleneck and will
divert some of the I/O request to use the main storage pool. The net
of all this is a complex equation but we've observed easily 5000-8000
synchronous writes per SSD up to 3 devices (or 6 in mirrored pairs).
Using smaller working set which creates less competition for CPU
resources we've even observed 48K synchronous writes per second.
Cycles per Bytes : 30-40 cycles per byte for NFS and CIFS
Once we include the full NFS or CIFS protocol, the efficiency was
observed to be in the 30-40 cycles per byte (8 to 10 of those coming
from the pure network component at regulat 1500 bytes MTU). More
studies are required to figure out the extent to which this is valid
but it's an interesting way to look at the problem. Having to run
disk I/O vs being serviced directly from cached data is expected to
exert an additional 10-20 cycles per byte. Obviously for metadata test
in which small amount of byte is transfered per operation, we probably
need to come up with a cycles/MetaOps invariant but that is still TBD.
Single Client NFS throughput : 1 TCP Window per round
trip latency.
This is one fundamental rule of network throughput but it's a
good occasion to refresh this in everyones mind. Clients, at least
solaris clients, will establish a single TCP connection to a server.
On that connection there can be a large number of unreleated requests
as NFS is a very scalable protocol. However, a single connection will
transport data at a maximum speed of a "socket buffer" divided by the
round trip latency. Since today's network speed, particularly in wide
area networks have grown somewhat faster than default socket buffers
we can see such things becoming performance bottleneck. Now given that
I work in Europe but my tests systems are often located in california,
I might be a little more sensitive than most to this fact. So one
important change we did early on, in this project was to simply bump
up the default socket buffers in the 7000 line to 1MB. However for
read throughput under similar conditions, we can only advise you to do
the same to your client infrastructure.
Using ZFS as a Network Attach Controller and the Value of Solid State Devices
So Sun is coming out today with a line of Sun Storage 7000
systems that have ZFS as the integrated volume and filesystem manager
using both read and write optimized SSD. What is this
Hybrid Storage Pool
and why is this a
good performance architecture for storage ?
A write optimized SSD is a custom designed device for
the purpose of
accelerating operations of the ZFS intent log (ZIL). The ZIL is the
part of ZFS that manages the important synchronous operation
guaranteeing that such writes are acknowledged quickly to applications
while guaranteeing persistence in case of outage. Data stored in the
ZIL is also kept in memory until ZFS issue the next Transaction Groups
(every few seconds).
The ZIL is what stores data urgently (when application is waiting) but
the TXG is what stores data permanently. The ZIL on-disk blocks are
only ever re-read after a failure such as power outage. So the SSDs
that are used to accelerate the ZIL are write-optimized : they need to handle data at
low latency on writes; reads are unimportant.
The TXG is an operation that is asynchronous to applications : apps
are generally not waiting for transactions groups to commit. The
exception here is when data is generated at a rate that exceeds the
TXG rate for a sustained period of time. In this case, we become
throttled by the pool throughput. In a NAS storage this will rarely
happen since network connectivity even at GB/s is still much less that
what storage is capable of and so we do not generate the imbalance.
The important thing now is that in a NAS server, the controller is also
running a file level protocol (NFS or CIFS) and so is knowledgeable
about the nature (synchronous or not) of the requested writes. As such
it can use the accelerated path (the SSD) only for the necessary
component of the workloads. Less competition for these devices means
we can deliver both high throughput and low latency together in the
same consolidated server.
But here is where is gets nifty. At times, a NAS server might
receive a huge synchronous request. We've observed this for instance
due to fsflush running on clients which will turn non-synchronous
writes into a massive synchronous one. I note here that a way to
reduce this effect, is to tune up fsflush (to say 600). This is
commonly done to reduce the cpu usage of fsflush but will be welcome
in the case of client interacting with NAS storage. We can also
disable page flushing entirely by setting dopageflush to 0. But that
is a client issue. From the perspective of the server, we still need
as a NAS to manage large commit request.
When subject to such a workload, say 1GB commit, ZFS being all aware
of the situation, can now decide to bypass the SDD device and issue
request straight to disk based pool blocks. It would do so for 2
reasons. One is that the pool of disks in it's entirety has more
throughput capabilities than the few write optimized SSD and so we will
service this request faster. But more importantly, the value of the
SSD is in it's latency reduction aspect. Leaving the SSDs available to
service many low latency synchronous writes is considered valuable
here. Another way to say this is that large writes are generally well
served by regular disk operations (they are throughput bound) whereas
small synchronous writes (latency bound) can and will get help from
the SSDs.
Caches at work
On the read path we also have custom designed read optimized
SSDs to fit in these OpenStorage platforms. At Sun, we just believe
that many workloads will naturally lend to caching technologies. In a
consolidated storage solution, we can offer up to 128GB of primary
memory based caching and approximately 500GB of SSD based caching.
We also recognized that the latency delta between memory cached
response and disk response was just too steep. By inserting a layer
of SSD between memory and disk, we have this intermediate step
providing lower latency access than disk to a working set which is
now many times greater than memory.
It's important here to understand how and when these read
optimized SSD will work. The first thing to recognized is that the SSD
will have to be primed with data. They feed off data being evicted
from the primary caches. So their effect will not immediately seen at
the start of a benchmarks. Second, one of the value of read optimized
SSD is truly in low latency responses to small requests. Small request
here means things of the order of 8K in size. Such request will occur
either when dealing with small files (~8K) or if dealing with larger
size but with fix record based application, typically a database. For
those application it is customary to set the recordsize and this will
allow those new SSDs to become more effective.
Our read optimized SSD can service up to 3000 read IOPS (see Brendan's work
on the
L2 ARC)
and this is close or better to what a 24 x 7.2 RPM disks JBOD can do. But the
key point is that the low latency response means it can do so using
much fewer threads that would be necessary to reach the same level on
a JBOD. Brendan demonstrated here that the response time of these
devices can be 20 times faster than disks and 8 to 10 times faster
from the client's perspective. So once data is installed in the
SSD, users will see their requests serviced much faster
which means we are less likely to be subject to queuing delays.
The use of read optimized SSD is configurable in the Appliance. Users
should learn to identify the part of their datasets that end up gated
by lightly threaded read response time. For those workloads enabling
the secondary cache is one way to deliver the value of the read optimized
SSD. For those filesystems, if the workload contains small files (such
as 8K) there is no need to tune anything, however for large files
access in small chunks setting the filesystem recordsize to 8K is
likely to produce the best response time.
Another benefit to these SSDs will be in the $/IOPS case. Some
workloads are just IOPS hungry while not necessarely huge block
consumers. The SSD technology offers great advantages in this space
where a single SDD can deliver the IOPS of a full JBOD at a fraction
of the cost. So with workloads that are more modestly sized but IOPS
hungry a test drive of the SSD will be very interesting.
It's also important to recognized that these systems are used in
consolidation scenarios. It can be that some part of the applications
will be sped up by read or write optimized SSD, or by the large memory
based caches while other consolidated workloads can exercise other
components.
There is another interesting implication to using SSD in the
storage in regards to clustering. The read optimized ssd acting as
caching layers actually never contain critical data. This means those
SSD can go into disk slots of head nodes since there is no data to be
failed over. On the other hand, write optimized SSD will store data
associated with the critical synchronous writes. But since those are located in
dual-ported backend enclosures, not the head nodes, it implies that,
during clustered operations, storage head nodes do not have to
exchange
any user level data.
So by using ZFS and read and write optimized SSDs, we can deliver low
latency writes for application that rely on them, and good throughput
for synchronous and non synchronous case using cost effective SATA
drives. Similarly on the read size, the high amount of primary and
secondary caches enables delivering high IOPS at low latency (even if
the workload is not highly threaded) and it can do so using the more
cost and energy efficient SATA drive.
Our architecture allows us to take advantage of the latency
accelerators while never being gated by them.
Designing Performance Metrics for Sun Storage 7000
One of the necessary checkpoint before launching a product is to be
able to assess it's performance. With Sun Storage 7xxx we had a
challenge in that the only NFS benchmark of notoriety was SPEC
SFS. Now this benchmark will have it's supporters and some customers
might be attached to it but it's important to understand what a
benchmarks actually says.
These SFS benchmark is a lot about "cache busting" the server : this is
interesting but at Sun we think that Caches are actually helpful in
real scenarios. Data goes in cycles in which it becomes hot at times.
Retaining that data in cache layers allow much lower latency access,
and much better human interaction with storage engines. Being a cache
busting benchmark, SFS numbers end up as a measure of the number of
disk rotation attached to the NAS server. So good SFS result requires
100 or 1000 of expensive, energy hungry 15K RPM spindles. To get good
IOPS, layers of caching are more important to the end user experience
and cost efficiency of the solution.
So we needed another way to talk about performance. Benchmarks tend to
test the system in peculiar ways that not necessarely reflect the
workloads each customer is actually facing. There are very many
workload generators for I/O but one interesting one that is OpenSource
and extensible is
Filebench
available in
Source.
So we used filebench to gather basic performance information about our
system with the hope that customers will then use filebench to
generate profiles that map to their own workloads. That way, different
storage option can be tested on hopefully more meaningful tests than
benchmarks.
Another challenge is that a NAS server interacts with client system
that themselve keep a cache of the data. Given that we wanted to
understand the back-end storage, we had to setup the tests to avoid
client side caching as much as possible. So for instance between the
phase of file creation and the phase of actually running the tests we
needed to clear the client caches and at times the server caches as
well. These possibilities are not readily accessible with the
simplest load generators and we had to do this in rather ad-hoc
fashion. One validation of our runs was to insure that the amount of
data transfered over the wire, observed with
Analytics was compatible
with the aggregate throughput measured at the client.
Still another challenge was that we needed to test a storage system
designed to interact with large number of clients. Again load
generators are not readily setup to coordinate multiple client and
gather global metrics. During the course of the effort filebench did
come up with a clustered mode of operation but we actually where too
far engaged in our path to take advantage of it.
This coordination of client is important because, the performance
information we want to report is actually the one that is delivered to
the client. Now each client will report it's own value for a given
test and our tool will sum up the numbers; but such a Sum is only
valid inasmuch as the tests ran on the clients in the same timeframe.
The possibility of skew between tests is something that needs to be
monitored by the person running the investigation.
One way that we increased this coordination was that we
divided our tests in 2 categories; those that required precreated
files, and those that created files during the timed portion of the
runs. If not handled properly, file creation would actually cause
important result skew. The option we pursued here was to have a
pre-creation phase of files that was done once. From that point, our
full set of metrics could then be run and repeated many times with
much less human monitoring leading to better reproducibility of
results.
Another goal of this effort was that we wanted to be able to run our
standard set of metrics in a relatively short time. Say less than 1
hours. In the end we got that to about 30 minutes per run to gather 10
metrics. Having a short amount of time here is important because there
are lots of possible ways that such test can be misrun. Having someone
watch over the runs is critical to the value of the output and to it's
reproducibility. So after having run the pre-creation of file
offline, one could run many repeated instance of the tests validating
the runs with
Analytics and through general observation of the system
gaining some insight into the meaning of the output.
At this point we were ready to define our metrics.
Obviously we needed streaming reads and writes. We needed ramdom reads.
We needed small synchronous writes important to Database workloads and
to the NFS protocol. Finally small filecreation and stat operation
completed the mix. For random reading we also needed to distinguish
between operating from disks and from storage side caches, an
important aspect of our architecture.
Now another thing that was on my mind was that, this is not a
benchmark. That means we would not be trying to finetune the metrics
in order to find out just exactly what is the optimal number of
threads and request size that leads to best possible performance from
the server. This is not the way your workload is setup. Your number of
client threads running is not elastic at will. Your workload is what
it is (threading included); the question is how fast is it being
serviced.
So we defined precise
per client workloads with preset number
of thread running the operations. We came up with this set just as an
illustration of what could be representative loads :
1- 1 thread streaming reads from 20G uncached set, 30 sec.
2- 1 thread streaming reads from same set, 30 sec.
3- 20 threads streaming reads from 20G uncached set, 30 sec.
4- 10 threads streaming reads from same set, 30 sec.
5- 20 threads 8K random read from 20G uncached set, 30 sec.
6- 128 threads 8K random read from same set, 30 sec.
7- 1 thread streaming write, 120 sec
8- 20 threads streaming write, 120 sec
9- 128 threads 8K synchronous writes to 20G set, 120 sec
10- 20 threads metadata (fstat) IOPS from pool of 400k files, 120 sec
11- 8 threads 8K file create IOPS, 120 sec.
For each of the 11 metrics, we could propose mapping these to relevant industries :
1- Backups, Database restoration (source), DataMining , HPC
2- Financial/Risk Analysis, Video editing, HPC
3- Media Streaming, HPC
4- Video Editing
5- DB consolidation, Mailserver, generic fileserving, Software development.
6- DB consolidation, Mailserver, generic fileserving, Software development.
7- User data Restore (destination)
8- Financial/Risk Analysis, backup server
9- Database/OLTP
10- Wed 2.0, Mailserver/Mailstore, Software Development
11- Web 2.0, Mailserver/Mailstore, Software Development
We managed to get all these tests running except the fstat (test 10)
due to a technicality in filebench. Filebench insisted on creating
the files up front and this test required thousands of them; moreover
filebench used a method that ended up single threaded to do so and in
the end, the stat information was mostly cached on the client. While
we could have plowed through some of the issues the conjunctions of
all these made us put the fstat test on the side for now.
Concerning thread counts, we figured that single stream read test was
at times critical (for administrative purposes) and an interesting
measure of the latency. Test 1 and 2 were defined this way with test
1 starting with cold client and server caches and test 2 continuing
the runs after having cleared the client cache (but not the server)
thus showing the boost from server side caching. Test 3 and 4 are
similarly defined with more threads involved for instance to mimic a
media server. Test 5 and 6 did random read tests, again with test 5
starting with a cold server cache and test 6 continuing with some of
the data precached from test 5. Here, we did have to deal with client
caches trying to insure that we don't hit in the client cache too much
as the run progressed. Test 7 and 8 showcased streaming writes for
single and 20 streams (per client). Reproducibility of test 7 and 8
is more difficult we believe because of client side
fsflush issue. We
found that we could get more stable results tuning fsflush on the
clients. Test 9 is the all important synchronous write case (for
instance a database). This test truly showcases the benefit of our
write side SSD and also shows why tuning the recordsize to match ZFS
records with DB accesses is important. Test 10 was inoperant as
mentioned above and test 11 filecreate, completes the set.
Given that those we predefined test definition, we're very happy to
see that our numbers actually came out really well with these tests
particularly for the Mirrored configs with write optimized SSDs.
See for instance results obtained by
Amitabha Banerjee .
I should add that these can now be used to give ballpark estimate of the
capability of the servers. They were not designed to deliver the
topmost numbers from any one config. The variability of the runs are
at times more important that we'd wish and so your mileage will
vary. Using
Analytics to observe the running system can be quite
informative and a nice way to actually demo that capability. So use
the output with caution and use your own judgment when it comes to
performance issues.

mardi novembre 04, 2008
People ask: where are we with ZFS performance ?
The standard answer to any computer performance question is
almost always : "it depends" which is semantically
equivalent to "I don't know". The better answer is to state
the dependencies.
I would certainly like to see every performance issue studied with a
scientific approach. OpenSolaris and Dtrace are just incredible
enablers when trying to reach root cause and finding those causes is
really the best way to work toward delivering improved performance.
More generally tough, people use common wisdom or possible faulty
assumption to match their symptoms with that of other similar reported
problems. And, as human nature has it, we'll easily blame the
component we're least familiar with for problems. So we often end up
with a lot of report of ZFS performance that once, drilled down,
become either totally unrelated to ZFS (say HW problems) , or
misconfiguration, departure from Best Practices or, at times,
unrealistic expectations.
That does not mean, there are no issues. But it's important
that users can more easily identify known issues, schedule
for fixes, workarounds etc. So anyone deploying ZFS should
really be familiar with those 2 sites :
ZFS Best Practices and
Evil Tuning Guide
That said, what are real commonly encountered performance problems
I've seen and where do we stand ?
Writes overunning memory
That is a real problem that was fixed last March and is integrated in
the Solaris U6 release. Running out of memory causes many different
types of complaints and erratic system behavior. This can happen
anytime a lot of data is created and streamed at rate greater than
that which can be set into the pool. Solaris U6 will be an important
shift for customers running into this issue. ZFS will still try to
use memory to cache your data (a good thing) but the competition this
creates for memory resources will be much reduced. The way ZFS is
designed to deal with this contention (ARC shrinking) will need a new
evaluation from the community. The lack of throttling was a great
impairement to the ability of the ARC to give back memory under
pressure. In the mean time lots of people are capping their arc size
with success as per the Evil Tuning guide.
For more on this topic check out :
The new ZFS write throttle
Cache flushes on SAN storage
This is a common issue we hit in the entreprise. Although it will
cause ZFS to be totally underwhelming in terms of performance, it's
interestingly not a sign of any defect in ZFS. Sadly this touches
customers that are the most performance minded. The issue is somewhat
related to ZFS and somewhat to the Storage. As is well documented
elsewhere, ZFS will, at critical times, issue "cache flush" request to
the storage elements on which is it layered. This is to take into
account the fact that storage can be layered on top of _volatile_
caches that do need to be set on stable storage for ZFS to reach it's
consistency points. Entreprise Storage Arrays do not use _volatile_
caches to store data and so should ignore the request from ZFS to
"flush caches". The problem is that some arrays don't. This
misunderstanding between ZFS and Storage Arrays leads to underwhelming
performance. Fortunately we have an easy workaround that can be used
to quickly identify if this is indeed the problem : setting
zfs_nocacheflush (see evil tuning guide). The best workaround here is
to configure the storage with the setting to indeed ignore "cache
flush". And we also have the option of tuning sd.conf on a per array
basis. Refer again to the evil tuning guide for more detailed
information.
NFS slow over ZFS (Not True)
This is just not generally true and often a side effect of the
previous Cache flush problem. People have used storage arrays to
accelerate NFS for long time but failed to see the expected gains with
ZFS. Many sighting of NFS problems are traced to this.
Other sightings involve common disks with volatile
caches. Here the performance delta observed are rooted in
the stronger semantics that ZFS offer to this operational
model. See
NFS and ZFS for a more detailed description of the
issue.
While I don't consider ZFS as generally slow serving NFS, we did
identify in recent months a condition that effects high thread count
of synchronous writes (such as a DB). This issue is fixed in the
Solaris 10 Update 6 (
CR 6683293).
I would encourage you to be familiar to where we stand regarding ZFS
and NFS because, I know of no big gapping ZFS over NFS problems (if
there were one, I think I would know). People just need to be aware
that NFS is a protocol need some type of accelaration (such as NVRAM)
in order to deliver a user experience close to what a direct attach
filesystem provides.
ZIL is a problem (Not True)
There is a wide perception that the ZIL is the source of performance
problems. This is just a naive interpretation of the facts. The ZIL
serves a very fundamental component of the filesystem and does that
admirably well. Disabling the synchronous semantics of a filesystem
will necessarely lead to higher performance in a way that is totally
misleading to the outside observer. So while we are looking at further
zil improvements for large scale problems, the ZIL is just not today
the source of common problems. So please don't disable this unless you
know what you're getting into.
Random read from Raid-Z
Raid-Z is a great technology that allows to store blocks on top of
common JBOD storage without being subject to raid-5 write hole
corruption (see : http://blogs.sun.com/bonwick/entry/raid_z). However
the performance characteristics of raid-z departs significantly from
raid-5 as to surprise first time users. Raid-Z as currently
implemented spreads blocks to the full width of the raid group and
creates extra IOPS during random reading. At lower loads, the latency
of operations is not impacted but sustained random read loads can
suffer. However, workloads that end up with frequent cache hits will
not be subject to the same penalty as workloads that access vast
amount of data more uniformly. This is where one truly needs to say,
"it depends".
Interestingly, the same problem does not affect Raid-Z streaming
performance and won't affect workloads that commonly benefit from
caching. That said both random and streaming performance are
perfectible and we are looking at a number different ways to improve
on this situation. To better understand Raid-Z, see one of my very
first ZFS entry on this topic :
Raid-Z
CPU consumption, scalability and benchmarking
This is an area we will need to make more studies. With todays very
capable multicore systems, there are many workloads that won't suffer
from the CPU consumptions of ZFS. Most systems do not run at 100% cpu
bound (being more generally constrained by disk, networks or
application scalability) and the user visible latency of operations
are not strongly impacted by extra cycles spent in say the ZFS
checksumming.
However, this view breaks down when it comes to system benchmarking.
Many benchmarks I encounter (the most crafted ones to boot) end up as
host CPU efficiency benchmarks : How many Operations can I do on this
system given large amount of disk and network resources while
preserving some level X of response time. The answer to this question
is purely the reverse of the cycles spent per operation.
This concern is more relevant when the CPU cycles spent in managing
direct attach storage and filesystem is in direct competition with
cycles spent in the application. This is also why database
benchmarking is often associated with using raw device, a fact must
less encountered in common deployment.
Root causing scalability limits and efficiency problems is just part of the never ending performance optimisation
of filesystems.
Direct I/O
Directio has been a great enabler of database performance in other
filesystems. The problem for me is that Direct I/O is a group of
improvements each with their own contribution to the end result. Some
want the concurrent writes, some wants to avoid a copy, some wants to
avoid double caching, some don't know but see performance gains when
turned on (some also see a degradation). I note that concurrent writes
has never been a problem in ZFS and that the extra copy used when
managing a cache is generally cheap considering common DB rates of
access. Acheiving greater CPU efficiency is certainly a valid goal
and we need to look into what is impacting this in common DB
workloads. In the mean time, ZFS in OpenSolaris got a new feature to
manage the cachebility of Data in the ZFS ARC. The per filesystem
"primarycache" property will allow users to decide if blocks should
actually linger in the ARC cache or just be transient. This will
allow DB deployed on ZFS to avoid any form of double caching that
might have occured in the past.
ZFS Performance is and will be a moving target for some time in the
future. Solaris 10 Update 6 with a new write throttle, will be a
significant change and then Opensolaris offers additional
advantages. But generally just be skeptical of any performance issue that is
not root caused: the problem might not be where you expect it