[Openstack] [Swift] XFS extended attribute performance
Samuel Merritt
sam at swiftstack.com
Tue Mar 24 23:58:04 UTC 2015
On 3/24/15 2:52 PM, Shrinand Javadekar wrote:
> Hi,
>
> I wrote a small microbenchmark for measuring the performance of
> extended attributes in XFS. In the experiment, I wrote 100K files,
> each with extended attributes. In one experiment, XFS was formatted
> with the default inode size of 256 bytes. In the other experiment, it
> was formatted with an inode size of 2048 bytes.
>
> Here's the actual code: http://pastie.org/private/2gnr3j9p5lxzzufdypkyzq
>
> I ran this using cProfile. The results suggest that time required for
> "xattr._xattr.fsetxattr" when the inode is 256 bytes is ~4 times that
> when the inode is 2048 bytes.
>
> When the inode is 256 bytes:
>
> ncalls tottime percall cumtime percall filename:lineno(function)
> 100000 3.933 0.000 3.933 0.000 {xattr._xattr.fsetxattr}
> 100000 4.344 0.000 4.344 0.000 {xattr._xattr.fsetxattr}
> 100000 4.624 0.000 4.624 0.000 {xattr._xattr.fsetxattr}
>
> When the inode is 2048 bytes:
>
> ncalls tottime percall cumtime percall filename:lineno(function)
> 100000 1.239 0.000 1.239 0.000 {xattr._xattr.fsetxattr}
> 100000 1.102 0.000 1.102 0.000 {xattr._xattr.fsetxattr}
> 100000 1.067 0.000 1.067 0.000 {xattr._xattr.fsetxattr}
>
> I will delve into more elaborate experiments with Swift and XFS
> filesystems formatted with different inode sizes. However, before
> that, I wanted to check if the above values are plausible and/or get
> suggestions around this microbenchmark.
The benchmark makes sense. The code (reproduced below in case that paste
goes away someday [1]) is setting the xattr "user.swift.metadata" (19
bytes) to a value of length 228, for a total of 247 bytes.
If the extended attributes will fit into the inode, then XFS will store
them there. However, if the extended attributes do not fit into the
inode, then the extended attributes are stored outside the inode in one
or more blocks. See [2] for more details.
It's important to note that *all* the extended attributes are stored in
the *same place*. If everything fits in the inode, then all extended
attributes live in the inode. If the extended attributes, taken
together, exceed the available inode space by just 1 byte, then all the
extended attributes are kicked out of the inode and off to an extents block.
Thus, with a 256-byte inode and a 247-byte payload, there's not room in
the inode with all the other stuff that lives in there for the extended
attributes, so they spill to extents. With a 2 KiB inode, there's more
than enough room.
> If these values make sense, will this translate into improved Swift performance?
Maybe(TM). It depends on your workload. When you make inodes bigger,
fewer of them fit in the kernel's buffer cache, possibly resulting in
more work. On the other hand, when you make them smaller, then you
always get xattrs spilled to extents.
Also, it's affected by what your users do. Are your users storing lots
of metadata (X-Object-Meta-*) on their objects? Are you using middleware
that stores lots of sysmeta (X-Object-Sysmeta-*) on your objects? Are
you running SELinux, which uses lots of xattrs for its own purposes?
Further, I think the benchmarking script is too naive to really get at
the key improvement here: avoiding seeks. If the xattrs live in the
inode, then we get them essentially for free when we open() the file. If
the xattrs live in extents, then at least one random IO is required to
fetch them. The improvement shown here is on the order of 30
microseconds, while an extra disk seek is more like 10-20 *milliseconds*
(on spinning platters). If you really want to measure the performance
gain, you'll need to drop the buffer cache each time and fsync() when
you're done.
[1]
============
#!/usr/bin/python
import xattr
prefix = "/srv/node/r1/"
for i in range (100000):
fd = open(prefix + "file-" + str(i), 'w')
fd.write("Some text")
xattr.setxattr(fd, "user.swift.metadata",
"U.Content-Lengthq.U.166U.nameq.U'/AUTH_admin/container-test/testxattr.pyq.U.X-Object-Meta-MtimeU.1426996406.379914q.U.ETagq.U
bab3674eed1a8725793f2d2de21f50a9q.U.X-Timestampq.U.1426996448.35449U.Content-Typeq.U.text/x-pythonq.u.")
fd.flush()
fd.close()
============
[2]
http://xfs.org/docs/xfsdocs-xml-dev/XFS_Filesystem_Structure/tmp/en-US/html/Extended_Attributes.html
More information about the Openstack
mailing list