I recently got a chance of experimenting mapreduce over several opensource object storages. Openstack swift is definitely one well known object storage service. However, I found it non-trivial to set it up for evaluation. Therefore, I put some notes below.
This article is only for os=Ubuntu 14.04 and swift=liberty. I noticed that the newer versions of swift is with much better documentation, which is much easier to follow. The appendix contains my early trials of installing swift from source.
Read the followings
- http://stackoverflow.com/questions/19004503/the-relationship-between-endpoints-regions-etc-in-keystone-openstack
- Part 1. Fundamentals and Architecture in “Openstack Swift - Using, Administering, and Developing for Swift Object Storage”
Make sure you have some sense for concepts including user, role, tenant, project, endpoint, proxy server, account server, object server, rings, and etc.
To my understanding, they are:
- user: a real user, or a service
- role: role of users, corresponding to a set of permissions
- tenant = project: a set of users
- endpoint: the entry point urls of openstack services
- proxy server: handling user requests in swift
- account server: handling user account in swift, also used as domain or primary namespace
- object server: handling object storage in swift
- rings: the consistent hashing algorithm used by swift
- keystone: the authentication service in openstack. Key concepts on keystone can be found here
Setup keynote and swift
Install dependencies
Install MariaDB (or MySQL) and memcache following page
Install keystone following page1 and page2. Note that if you want to run mapreduce over swift, you can not use the TempAuth approach. Read this page for more details.
Install swift following page1, page2, and page3. You can start the swift service with
1 | swift-init all start |
Setup Hadoop
- Setup Hadoop with version >= 2.3 and configure it following page1 and page2.
- Make sure SwiftNativeFileSystem is in the classpath, read this page for any problem you find.
- Configure etc/hadoop/core-site.xml,add following contents:
1 | <configuration> |
Verify all setup
- create a container (swift post nameofcontainer). Important! the name should be only consist of letters. No ‘_’ is allowed.
- upload a file (swift upload nameofcontainer nameoffile).
- hdfs dfs -ls swift://nameofcontainer.SwiftTest/. This should show you files you uploaded previously.
- hadoop distcp nameoffile swift://mycontainer.SwiftTest/nameoffile
Appendix: Install swift from source
Dependencies
From the swift book
1 | apt-get install git curl gcc memcached rsync sqlite3 xfsprogs \ |
1 | apt-get install python-coverage python-dev python-nose \ |
Install the latest liberasurecode (as per some post, may not be necessary)
1 | sudo apt-get install build-essential autoconf automake libtool |
Install the Swift CLI
1 | cd /opt |
I run into a problem of invalid format of the requirement.txt. You may need to do some editing in that case.
Install the Swift
1 | cd /opt |
The above is from the swift book. But I realized I still need to run “sudo pip install -r requirements.txt” before the setup*
Another issue I found is that it takes forever to pip install cryptography in the requirements.txt. I searched in Google where some guy said it took 20 min for building. For me, after 20 min, it still hanged there.
I tried to install all dependencies manually, as follows without the cryptography. After that, it was installed successfully:
1 | Requirement already satisfied (use --upgrade to upgrade): cryptography in /usr/local/lib/python2.7/dist-packages |
Copy in Swift configuration files
1 | mkdir -p /etc/swift |
In this setup, we rely on tempauth for authentication.
Config the swift.conf
Setting the hash path prefix and suffix
These two random strings are used to determine the hash result of the partitions on the rings. They are supposed to be confidential.
1 | swift_hash_path_suffix = random_32_length_string1 |
You can use
1 | head -c 32 /dev/random | base64 |
to get one random 32 length string.
The storage policy
You can custermize the storage policy as per the swift book, but it is optional.
Build the rings
The 3 parameters are part_power, replicas, min_part_hours
- part_power: the number of partitions in the storage cluster. The typical setting is log_2 ( 100 maximun number of disks ). For this setup, it is log_2 (100 1) which is close to 7.
- replicas: in this setup, there is only one drive. Therefore, only 1 replica is allowed.
- min_part_hours: the default is 24 hours. Tune it as per the swift book or the official document.
1 | cd /etc/swift |
Prepare the drives
You can use a disk or chop off disk space from existing disk to provide storage for swift. Follow the step 2 of this article. Copied here:
Attach a disk which would be used for storage or chop off some disk space from the existing disk.
Using additional disks:
Most likely this is done when there is large amount of data to be stored. XFS is the recommended filesystem and is known to work well with Swift. If the additional disk is attached as /dev/sdb then following will do the trick:
1 | # fdisk /dev/sdb |
Chopping off disk space from the existing disk:
We can chop off disk from existing disks as well. This is usually done for smaller installations or for “proof-of-concept” stage. We can use XFS like before or we can use ext4 as well.
1 | # truncate --size=2G /tmp/swiftstorage |
In either case, you need to
1 | chown -R swift:swift /srv/node/partition1 |
Also, you need to mount automatically after system reboot. So put the mount command line into a script, e.g., /opt/swift/bin/mount_devices. Then add a file start_swift.conf under /etc/init/ with content
1 | description "mount swift drives" |
Make sure to make the script runnable
1 | chmod +x /opt/swift/bin/mount_devices |
Add the drives to the rings
The single parameter 100 is the weight for load balancing. Note that the partition1 in the command is in the path of /srv/node/partition1. If you change the path, you need to change both places. It is not the name of the device in /dev/sda, for example. Make sure about the IPs and the PORTs. They are the address of the processes (account, container, and object). I was blocked by the port for quite a while, simply because the default ports in the conf files are different from the ones used below (not sure why…).
1 | swift-ring-builder account.builder add r1z1-127.0.0.1:6002/partition1 100 |
Rebalance the rings to create them actually.
1 | swift-ring-builder account.builder rebalance |
You will find the *.ring.gz files and a backup folder.
Configure the logs
put a file named 0-swift.conf under /etc/rsyslog.d directory, containing only one line:
1 | local0.* /var/log/swift/all.log |
And then create the directory and set the right permissions.
1 | mkdir /var/log/swift |
Start the proxy server
1 | swift-init proxy start |
If you see warning messages as discussed in this post. You can follow the solutions there, copied here:
1 | curl -o libisal2_2.15.0-3~bpo14.04+1_amd64.deb http://mitaka-trusty.pkgs.mirantis.com/debian/pool/trusty-mitaka-backports/main/l/libisal/libisal2_2.15.0-3~bpo14.04+1_amd64.deb |
Configure tempauth in proxy-server.conf
We rely on tempauth for authentication in this setup. If you are using keystone, follow this post or this one.
First, start the memcache:
1 | service memcached start |
Add your users to proxy-server.conf under the tempauth block.
1 | [filter:tempauth] |
The syntax is
1 | user_$SWIFTACCOUNT_$SWIFTUSER = $KEY [group] [group] [...] [storage_url] |
which means you can configure the user for each storage url.
Then, modify these two options:
1 | allow_account_management = true |
Start the servers
Create the cache directory
1 | mkdir -p /var/swift/recon |
Start the services after making sure the conf files are right, especially the ip and port. The ip is typically set to 0.0.0.0 and the port should be the same as adding the drives.
1 | swift-init account start |
Then, restart the proxy server
1 | swift-init proxy restart |
Verify the setup
Send in the authentication (note that I’m using the admin user defined in the proxy-server.conf with group admin and password admin):
1 | curl -v -H 'X-Auth-User: admin:admin' -H 'X-Auth-Key: admin' http://localhost:8080/auth/v1.0/ |
The above will get you the X-Auth-Token if everything is right. For instance,
1 | * Hostname was NOT found in DNS cache |
Next, use the token to access the account by
1 | curl -v -H 'X-Storage-Token: AUTH_tka1a0d192e57746839c1749f238ba5419' http://127.0.0.1:8080/v1/AUTH_admin/ |
the admin in the url AUTH_admin should be the same as the username. You should get something like follows.
1 | * Hostname was NOT found in DNS cache |
I was blocked here for quite a while simply because the port in the proxy-server.conf is 6202, not 6002. Be careful!!!
If you get something wrong, go to the log file (at /var/log/swift/all.log) and see the error message there.
You can further verify the setup by creating a container and upload/download a file with
1 | curl -v -H 'X-Storage-Token: AUTH_tka1a0d192e57746839c1749f238ba5419' -X PUT http://127.0.0.1:8080/v1/AUTH_admin/mycontainer |
In the last command line, we use swift client instead of curl. There are other subcommand other than upload. There are delete, download, list, post, and stat. To avoid putting the url and user info in every command, one could put the following into .bashrc
1 | export ST_AUTH=http://localhost:8080/auth/v1.0 |
Start the consistency processes
Swift relies on a few other processes for consistency purposes.
Edit (or create) the /etc/default/rsync file and add the following line:
1 | RSYNC_ENABLE=true |
Then, edit (or create) the /etc/rsyncd.conf file, adding the following:
1 | uid = swift |
Start the rsync service
1 | service rsync start |
Now, you can start the processes by
1 | swift-init account-replicator start |
One useful way of controlling these processes is by
1 | swift-init all start/stop/restart |
Setup on multiple nodes
The plan of deployment depends on the hardware. One need to read the part IV of the swift book before that. I found this article very well writen. One can learn the way of deployment for a small cluster.
There are a few points one should keep in mind.
- Copy the swift.conf file to all nodes;
- Add the drives across all nodes to the rings;
- Copy the rings to all nodes;
References
- Install a Stand-alone, Multi-node OpenStack Swift Cluster with VirtualBox or VMware Fusion and Vagrant (https://thornelabs.net/2014/07/14/install-a-stand-alone-multi-node-openstack-swift-cluster-with-virtualbox-or-vmware-fusion-and-vagrant.html)
- OpenStack 101: How to Setup OpenStack Swift (http://blog.adityapatawari.com/2014/01/openstack-101-how-to-setup-openstack_12.html)
- OpenStack Swift (the swift book)