openstack-manuals/doc/config-reference/object-storage/section_object-storage-features.xml
Diane Fleming 64b6c9261e Folder rename, file rename, flattening of directories
Current folder name	New folder name	        Book title
----------------------------------------------------------
basic-install 	        DELETE
cli-guide	        DELETE
common	                common
NEW	                admin-guide-cloud	Cloud Administrators Guide
docbkx-example	        DELETE
openstack-block-storage-admin 	DELETE
openstack-compute-admin 	DELETE
openstack-config 	config-reference	OpenStack Configuration Reference
openstack-ha 	        high-availability-guide	OpenStack High Availabilty Guide
openstack-image	        image-guide	OpenStack Virtual Machine Image Guide
openstack-install 	install-guide	OpenStack Installation Guide
openstack-network-connectivity-admin 	admin-guide-network 	OpenStack Networking Administration Guide
openstack-object-storage-admin 	DELETE
openstack-security 	security-guide	OpenStack Security Guide
openstack-training 	training-guide	OpenStack Training Guide
openstack-user 	        user-guide	OpenStack End User Guide
openstack-user-admin 	user-guide-admin	OpenStack Admin User Guide
glossary	        NEW        	OpenStack Glossary

bug: #1220407

Change-Id: Id5ffc774b966ba7b9a591743a877aa10ab3094c7
author: diane fleming
2013-09-08 15:15:50 -07:00

546 lines
28 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<section xml:id="configuring-object-storage-features"
xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="5.0">
<title>Configuring OpenStack Object Storage Features</title>
<section xml:id="object-storage-rate-limits">
<?dbhtml stop-chunking?>
<title>Throttling Resources by Setting Rate Limits</title>
<para>Rate limiting in OpenStack Object Storage is implemented
as a pluggable middleware that you configure on the proxy
server. Rate limiting is performed on requests that result
in database writes to the account and container sqlite
dbs. It uses memcached and is dependent on the proxy
servers having highly synchronized time. The rate limits
are limited by the accuracy of the proxy server
clocks.</para>
<section xml:id="configuration-for-rate-limiting">
<title>Configuration for Rate Limiting</title>
<para>All configuration is optional. If no account or
container limits are provided there will be no rate
limiting. Available configuration options include:</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-ratelimit.xml"/>
<para>The container rate limits are linearly interpolated
from the values given. A sample container rate
limiting could be:</para>
<para>container_ratelimit_100 = 100</para>
<para>container_ratelimit_200 = 50</para>
<para>container_ratelimit_500 = 20</para>
<para>This would result in:</para>
<table rules="all">
<caption>Values for Rate Limiting with Sample
Configuration Settings</caption>
<tbody>
<tr>
<td>Container Size</td>
<td>Rate Limit</td>
</tr>
<tr>
<td>0-99</td>
<td>No limiting</td>
</tr>
<tr>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>150</td>
<td>75</td>
</tr>
<tr>
<td>500</td>
<td>20</td>
</tr>
<tr>
<td>1000</td>
<td>20</td>
</tr>
</tbody>
</table>
</section>
</section>
<section xml:id="object-storage-healthcheck">
<title>Health Check</title>
<para>Health Check provides a simple way to monitor if the
swift proxy server is alive. If the proxy is access
with the path /healthcheck, it will respond with “OK”
in the body, which can be used by monitoring
tools.</para>
<xi:include href="../../common/tables/swift-account-server-filter-healthcheck.xml"/>
</section>
<section xml:id="object-storage-domain-remap">
<title>Domain Remap</title>
<para>Domain Remap is middleware that translates container
and account parts of a domain to path parameters that
the proxy server understands.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-domain_remap.xml"/>
</section>
<section xml:id="object-storage-cname-lookup">
<title>CNAME Lookup</title>
<para>CNAME Lookup is middleware that translates an
unknown domain in the host header to something that
ends with the configured storage_domain by looking up
the given domain's CNAME record in DNS.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-cname_lookup.xml"/>
</section>
<section xml:id="object-storage-tempurl">
<title>Temporary URL</title>
<para>Allows the creation of URLs to provide temporary
access to objects. For example, a website may wish to
provide a link to download a large object in Swift,
but the Swift account has no public access. The
website can generate a URL that will provide GET
access for a limited time to the resource. When the
web browser user clicks on the link, the browser will
download the object directly from Swift, obviating the
need for the website to act as a proxy for the
request. If the user were to share the link with all
his friends, or accidentally post it on a forum, etc.
the direct access would be limited to the expiration
time set when the website created the link. To create
such temporary URLs, first an
X-Account-Meta-Temp-URL-Key header must be set on the
Swift account. Then, an HMAC-SHA1 (RFC 2104) signature
is generated using the HTTP method to allow (GET or
PUT), the Unix timestamp the access should be allowed
until, the full path to the object, and the key set on
the account. For example, here is code generating the
signature for a GET for 60 seconds on
<code>/v1/AUTH_account/container/object</code>:
<programlisting language="python">
import hmac
from hashlib import sha1
from time import time
method = 'GET'
expires = int(time() + 60)
path = '/v1/AUTH_account/container/object'
key = 'mykey'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest()
</programlisting></para>
<para>Be certain to use the full path, from the /v1/
onward. Let's say the sig ends up equaling
da39a3ee5e6b4b0d3255bfef95601890afd80709 and expires
ends up 1323479485. Then, for example, the website
could provide a link to:
<programlisting>
https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709&amp;
temp_url_expires=1323479485
</programlisting></para>
<para>Any alteration of the resource path or query
arguments would result in 401 Unauthorized. Similarly,
a PUT where GET was the allowed method would 401. HEAD
is allowed if GET or PUT is allowed. Using this in
combination with browser form post translation
middleware could also allow direct-from-browser
uploads to specific locations in Swift. Note that
changing the X-Account-Meta-Temp-URL-Key will
invalidate any previously generated temporary URLs
within 60 seconds (the memcache time for the key).</para>
<para>A script called swift-temp-url distributed with swift source
code eases the temporary URL creation:
<programlisting>
$ bin/swift-temp-url GET 3600 /v1/AUTH_account/container/object mykey
/v1/AUTH_account/container/object?
temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91&amp;
temp_url_expires=1374497657
</programlisting>
The path returned by the above command is prefixed with swift
storage hostname.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-tempurl.xml"/>
</section>
<section xml:id="object-storage-name-check">
<title>Name Check Filter</title>
<para>Name Check is a filter that disallows any paths that
contain defined forbidden characters or that exceed a
defined length.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-name_check.xml"/>
</section>
<section xml:id="object-storage-constraints">
<title>Constraints</title>
<para>The <literal>swift-constraints</literal> section in
<filename>swift.conf</filename> allows modification
of internal limits within swift. These are advanced
features for tuning the performance of the cluster and
should be altered with caution.</para>
<table rules="all">
<caption>Configuration options for swift-constraints
in swift.conf</caption>
<tbody>
<tr>
<td>Option</td>
<td>Default</td>
<td>Description</td>
</tr>
<tr>
<td>max_file_size</td>
<td>5368709122</td>
<td>the largest "normal" object that can be
saved in the cluster. This is also the
limit on the size of each segment of a
"large" object when using the large object
manifest support. This value is set in
bytes. Setting it to lower than 1MiB will
cause some tests to fail. It is STRONGLY
recommended to leave this value at the
default (5 * 2**30 + 2).</td>
</tr>
<tr>
<td>max_meta_name_length</td>
<td>128</td>
<td>the max number of bytes in the utf8
encoding of the name portion of a metadata
header.</td>
</tr>
<tr>
<td>max_meta_value_lenth</td>
<td>256</td>
<td>the max number of bytes in the utf8
encoding of a metadata value</td>
</tr>
<tr>
<td>max_meta_count</td>
<td>90</td>
<td>the max number of metadata keys that can
be stored on a single account, container,
or object</td>
</tr>
<tr>
<td>max_meta_overall_size</td>
<td>4096</td>
<td>the max number of bytes in the utf8
encoding of the metadata (keys +
values)</td>
</tr>
<tr>
<td>max_object_name_length</td>
<td>1024</td>
<td>the max number of bytes in the utf8
encoding of an object name</td>
</tr>
<tr>
<td>container_listing_limit</td>
<td>10000</td>
<td>the default (and max) number of items
returned for a container listing
request</td>
</tr>
<tr>
<td>max_account_name_length</td>
<td>256</td>
<td>the max number of bytes in the utf8
encoding of an account name</td>
</tr>
<tr>
<td>max_container_name_length</td>
<td>256</td>
<td>the max number of bytes in the utf8
encoding of a container name</td>
</tr>
</tbody>
</table>
</section>
<section xml:id="object-storage-dispersion">
<title>Cluster Health</title>
<para>There is a
<literal>swift-dispersion-report</literal> tool
for measuring overall cluster health. This is
accomplished by checking if a set of deliberately
distributed containers and objects are currently in
their proper places within the cluster. For instance,
a common deployment has three replicas of each object.
The health of that object can be measured by checking
if each replica is in its proper place. If only 2 of
the 3 is in place the objects heath can be said to be
at 66.66%, where 100% would be perfect. A single
objects health, especially an older object, usually
reflects the health of that entire partition the
object is in. If we make enough objects on a distinct
percentage of the partitions in the cluster, we can
get a pretty valid estimate of the overall cluster
health. In practice, about 1% partition coverage seems
to balance well between accuracy and the amount of
time it takes to gather results. The first thing that
needs to be done to provide this health value is
create a new account solely for this usage. Next, we
need to place the containers and objects throughout
the system so that they are on distinct partitions.
The swift-dispersion-populate tool does this by making
up random container and object names until they fall
on distinct partitions. Last, and repeatedly for the
life of the cluster, we need to run the
swift-dispersion-report tool to check the health of
each of these containers and objects. These tools need
direct access to the entire cluster and to the ring
files (installing them on a proxy server will probably
do). Both <command>swift-dispersion-populate</command> and
<command>swift-dispersion-report</command> use the same configuration
file, <filename>/etc/swift/dispersion.conf</filename>.
Example dispersion.conf file:
<programlisting language="ini">
[dispersion]
auth_url = http://localhost:8080/auth/v1.0
auth_user = test:tester
auth_key = testing
</programlisting>
There are also options for the conf file for
specifying the dispersion coverage (defaults to 1%),
retries, concurrency, etc. though usually the defaults
are fine. Once the configuration is in place, run
swift-dispersion-populate to populate the containers
and objects throughout the cluster. Now that those
containers and objects are in place, you can run
swift-dispersion-report to get a dispersion report, or
the overall health of the cluster. Here is an example
of a cluster in perfect health:
<screen><prompt>$</prompt> <userinput>swift-dispersion-report</userinput>
<computeroutput>Queried 2621 containers for dispersion reporting, 19s, 0 retries
100.00% of container copies found (7863 of 7863)
Sample represents 1.00% of the container partition space
Queried 2619 objects for dispersion reporting, 7s, 0 retries
100.00% of object copies found (7857 of 7857)
Sample represents 1.00% of the object partition space
</computeroutput></screen>
Now, deliberately double the weight of a device in the
object ring (with replication turned off) and rerun
the dispersion report to show what impact that has:
<screen><prompt>$</prompt> <userinput>swift-ring-builder object.builder set_weight d0 200</userinput>
<prompt>$</prompt> <userinput>swift-ring-builder object.builder rebalance</userinput>
...
<prompt>$</prompt> <userinput>swift-dispersion-report</userinput>
<computeroutput>Queried 2621 containers for dispersion reporting, 8s, 0 retries
100.00% of container copies found (7863 of 7863)
Sample represents 1.00% of the container partition space
Queried 2619 objects for dispersion reporting, 7s, 0 retries
There were 1763 partitions missing one copy.
77.56% of object copies found (6094 of 7857)
Sample represents 1.00% of the object partition space
</computeroutput></screen>
You can see the health of the objects in the cluster
has gone down significantly. Of course, this test
environment has just four devices, in a production
environment with many devices the impact of one device
change is much less. Next, run the replicators to get
everything put back into place and then rerun the
dispersion report:
<programlisting>
... start object replicators and monitor logs until they're caught up ...
$ swift-dispersion-report
Queried 2621 containers for dispersion reporting, 17s, 0 retries
100.00% of container copies found (7863 of 7863)
Sample represents 1.00% of the container partition space
Queried 2619 objects for dispersion reporting, 7s, 0 retries
100.00% of object copies found (7857 of 7857)
Sample represents 1.00% of the object partition space
</programlisting>
Alternatively, the dispersion report can also be
output in json format. This allows it to be more
easily consumed by third party utilities:
<screen><prompt>$</prompt> <userinput>swift-dispersion-report -j</userinput>
<computeroutput>{"object": {"retries:": 0, "missing_two": 0, "copies_found": 7863, "missing_one": 0,
"copies_expected": 7863, "pct_found": 100.0, "overlapping": 0, "missing_all": 0}, "container":
{"retries:": 0, "missing_two": 0, "copies_found": 12534, "missing_one": 0, "copies_expected":
12534, "pct_found": 100.0, "overlapping": 15, "missing_all": 0}}</computeroutput></screen>
</para>
<xi:include href="../../common/tables/swift-dispersion-dispersion.xml"/>
</section>
<section xml:id="object-storage-slo">
<!-- Usage documented in http://docs.openstack.org/developer/swift/overview_large_objects.html -->
<title>Static Large Object (SLO) support</title>
<para>This feature is very similar to Dynamic Large Object
(DLO) support in that it allows the user to upload
many objects concurrently and afterwards download them
as a single object. It is different in that it does
not rely on eventually consistent container listings
to do so. Instead, a user defined manifest of the
object segments is used.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-slo.xml"/>
</section>
<section xml:id="object-storage-container-quotas">
<title>Container Quotas</title>
<para>The container_quotas middleware implements simple
quotas that can be imposed on swift containers by a
user with the ability to set container metadata, most
likely the account administrator. This can be useful
for limiting the scope of containers that are
delegated to non-admin users, exposed to formpost
uploads, or just as a self-imposed sanity
check.</para>
<para>Any object PUT operations that exceed these quotas
return a 413 response (request entity too large) with
a descriptive body.</para>
<para>Quotas are subject to several limitations: eventual
consistency, the timeliness of the cached
container_info (60 second ttl by default), and it's
unable to reject chunked transfer uploads that exceed
the quota (though once the quota is exceeded, new
chunked transfers will be refused).</para>
<para>Quotas are set by adding meta values to the
container, and are validated when set: <itemizedlist>
<listitem>
<para>X-Container-Meta-Quota-Bytes: Maximum
size of the container, in bytes.</para>
</listitem>
<listitem>
<para>X-Container-Meta-Quota-Count: Maximum
object count of the container.</para>
</listitem>
</itemizedlist>
</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-container-quotas.xml"/>
</section>
<section xml:id="object-storage-account-quotas">
<title>Account Quotas</title>
<para>The account_quotas middleware aims to block write
requests (PUT, POST) if a given account quota (in bytes)
is exceeded while DELETE requests are still
allowed.</para>
<para>The x-account-meta-quota-bytes metadata entry must
be set to store and enable the quota. Write requests
to this metadata entry are only permitted for resellers.
There isn't any account quota limitation on a reseller
account even if x-account-meta-quota-bytes is set.</para>
<para>Any object PUT operations that exceed the quota
return a 413 response (request entity too large) with
a descriptive body.</para>
<para>The following command uses an admin account that own
the Reseller role to set a quota on the test account:
<screen><prompt>$</prompt> <userinput>swift -A http://127.0.0.1:8080/auth/v1.0 -U admin:admin -K admin \
--os-storage-url=http://127.0.0.1:8080/v1/AUTH_test post -m quota-bytes:10000</userinput></screen>
Here is the stat listing of an account where quota has been set:
<screen><prompt>$</prompt> <userinput>swift -A http://127.0.0.1:8080/auth/v1.0 -U test:tester -K testing stat</userinput>
<computeroutput>Account: AUTH_test
Containers: 0
Objects: 0
Bytes: 0
Meta Quota-Bytes: 10000
X-Timestamp: 1374075958.37454
X-Trans-Id: tx602634cf478546a39b1be-0051e6bc7a</computeroutput></screen>
The command below removes the account quota:
<screen><prompt>$</prompt> <userinput>swift -A http://127.0.0.1:8080/auth/v1.0 -U admin:admin -K admin --os-storage-url=http://127.0.0.1:8080/v1/AUTH_test post -m quota-bytes:</userinput></screen>
</para>
</section>
<section xml:id="object-storage-bulk-delete">
<title>Bulk Delete</title>
<para>Will delete multiple files from their account with a
single request. Responds to DELETE requests with a header
'X-Bulk-Delete: true_value'. The body of the DELETE
request will be a newline separated list of files to
delete. The files listed must be URL encoded and in the
form:
<programlisting>
/container_name/obj_name
</programlisting>
</para>
<para>If all files were successfully deleted (or did not
exist) will return an HTTPOk. If any files failed to
delete will return an HTTPBadGateway. In both cases the
response body is a json dictionary specifying in the
number of files successfully deleted, not found, and a
list of the files that failed.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-bulk.xml"/>
</section>
<xi:include href="section_configure_s3.xml"/>
<section xml:id="object-storage-drive-audit">
<title>Drive Audit</title>
<para>The swift-drive-audit configuration items reference a script that can be run via cron to watch for bad drives. If
errors are detected, it will unmount the bad drive, so that OpenStack Object Storage can work
around it. It takes the following options:</para>
<xi:include href="../../common/tables/swift-drive-audit-drive-audit.xml"/>
</section>
<section xml:id="object-storage-form-post">
<title>Form Post</title>
<para>The Form Post middleware provides the ability to upload objects to
a cluster using an HTML form POST. The format of the form is:</para>
<programlisting>&lt;![CDATA[
&lt;form action="&lt;swift-url&gt;" method="POST"
enctype="multipart/form-data"&gt;
&lt;input type="hidden" name="redirect" value="&lt;redirect-url&gt;" /&gt;
&lt;input type="hidden" name="max_file_size" value="&lt;bytes&gt;" /&gt;
&lt;input type="hidden" name="max_file_count" value="&lt;count&gt;" /&gt;
&lt;input type="hidden" name="expires" value="&lt;unix-timestamp&gt;" /&gt;
&lt;input type="hidden" name="signature" value="&lt;hmac&gt;" /&gt;
&lt;input type="file" name="file1" /&gt;&lt;br /&gt;
&lt;input type="submit" /&gt;
&lt;/form&gt;]]&gt;
</programlisting>
<para>The <literal>swift-url</literal> is the URL to the Swift destination, such as:
<uri>https://swift-cluster.example.com/v1/AUTH_account/container/object_prefix</uri>
The name of each file uploaded will be appended to the <literal>swift-url</literal> given. So, you can upload
directly to the root of container with a url like:
<uri>https://swift-cluster.example.com/v1/AUTH_account/container/</uri>
Optionally, you can include an object prefix to better separate different users uploads, such as:
<uri>https://swift-cluster.example.com/v1/AUTH_account/container/object_prefix</uri>
</para>
<para>Note the form method must be POST and the enctype must be set as “multipart/form-data”.
The redirect attribute is the URL to redirect the browser to after the upload completes. The URL
will have status and message query parameters added to it, indicating the HTTP status code for the
upload (2xx is success) and a possible message for further information if there was an error (such
as “max_file_size exceeded”).
The max_file_size attribute must be included and indicates the largest single file upload that can
be done, in bytes.
The max_file_count attribute must be included and indicates the
maximum number of files that can be uploaded with the form. Include
additional <code>&lt;![CDATA[&lt;input type="file" name="filexx"/&gt;]]&gt;</code>
attributes if desired.
The expires attribute is the Unix timestamp before which the form must be submitted before it is
invalidated.
The signature attribute is the HMAC-SHA1 signature of the form. Here is sample code for computing
the signature:
<programlisting language="python">
import hmac
from hashlib import sha1
from time import time
path = '/v1/account/container/object_prefix'
redirect = 'https://myserver.com/some-page'
max_file_size = 104857600
max_file_count = 10
expires = int(time() + 600)
key = 'mykey'
hmac_body = '%s\n%s\n%s\n%s\n%s' % (path, redirect,
max_file_size, max_file_count, expires)
signature = hmac.new(key, hmac_body, sha1).hexdigest()
</programlisting>
The key is the value of the X-Account-Meta-Temp-URL-Key header on the account.
Be certain to use the full path, from the /v1/ onward.
The command line tool swift-form-signature may be used (mostly just when testing) to compute
expires and signature.
</para>
<para>
Also note that the file attributes must be after the other attributes in order to be processed
correctly. If attributes come after the file, they wont be sent with the subrequest (there is no
way to parse all the attributes on the server-side without reading the whole thing into memory to
service many requests, some with large files, there just isnt enough memory on the server, so
attributes following the file are simply ignored).</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-formpost.xml"/>
</section>
<section xml:id="object-storage-static-web">
<title>Static Websites</title>
<para>When configured, the StaticWeb WSGI middleware serves container
data as a static web site with index file and error file resolution and
optional file listings. This mode is normally only active for anonymous
requests.</para>
<xi:include href="../../common/tables/swift-proxy-server-filter-staticweb.xml"/>
</section>
</section>