SWIFT is the object storage service of openstack. Recently, I have summarized the source code in some articles. I would like to extend my gratitude to my blog for its in-depth explanation.
Code directory
Is its code directory
You can see several important folders: accout, ring, container, OBJ, and proxy.
The directory installed on the physical host is:
/usr/lib/python2.7/dist-packages/swift# lsaccount common container __init__.py __init__.pyc obj proxy
Third parties used
Swift uses the SQLite database for object information. SQLite is a lightweight database and an acid-compliant associated database management system. It is designed to be embedded and has been used in many embedded products, it occupies very low resources. In embedded devices, it may only need several hundred KB of memory. It supports mainstream operating systems such as Windows, Linux, and UNIX, and can be combined with many programming languages, such as TCL, C #, PHP, Java, and ODBC interfaces, similar to MySQL and PostgreSQL, the two world-renowned open-source database management systems, the processing speed is faster than that of them.
You can use the following method to output tables contained in the database:
import sqlite3cx=sqlite3.connect("./test.db")cu=cx.cursor()cu.execute("select name from sqlite_master where type='table'")print cu.fetchall()
To view the content of a table in a database, you can use the following statements to view the content of the container in test. DB:
import sqlite3cx=sqlite3.connect("./test.db")cu=cx.cursor()cu.execute("select * from container")print cu.fetchall()
You can go to the link on the official website to learn more about each function you are interested in. In fact, it can be used as a manual: Functions.
About Ring
A blog Analysis on ring is better: Ring.
Ring rebalance Mechanism
When the storage node in the cluster is down, the new (delete) Storage node, the new (delete) zone, and so on must change the ing relationship between the partition and node, the ring file needs to be updated, that is, the rebalance term seen in the swift document.
The rebalance definition in the source code is as follows: Swift/common/ring/builder. py
def rebalance(self): """ Rebalance the ring. This is the main work function of the builder, as it will assign and reassign partitions to devices in the ring based on weights, distinct zones, recent reassignments, etc. The process doesn't always perfectly assign partitions (that'd take a lot more analysis and therefore a lot more time -- I had code that did that before). Because of this, it keeps rebalancing until the device skew (number of partitions a device wants compared to what it has) gets below 1% or doesn't change by more than 1% (only happens with ring that can't be balanced no matter what -- like with 3 zones of differing weights with replicas set to 3). :returns: (number_of_partitions_altered, resulting_balance) """ self._ring = None if self._last_part_moves_epoch is None: self._initial_balance() self.devs_changed = False return self.parts, self.get_balance() retval = 0 self._update_last_part_moves() last_balance = 0 while True: reassign_parts = self._gather_reassign_parts() self._reassign_parts(reassign_parts) retval += len(reassign_parts) while self._remove_devs: self.devs[self._remove_devs.pop()['id']] = None balance = self.get_balance() if balance < 1 or abs(last_balance - balance) < 1 or \ retval == self.parts: break last_balance = balance self.devs_changed = False self.version += 1 return retval, balance
When constructing a new ring based on the original ring, swift-ring-builder first needs to recalculate the number of partitions required for each device. Then, collect the partitions to be reassigned. Cancel the partitions allocated to the removed device and add these partitions to the collection list. Unallocate more partitions randomly from devices with more than the number of required partitions and add them to the collection list. Finally, the partition in the collection list is re-allocated using a method similar to the initialization allocation.
Run the swift-ring-builder command locally to generate a new ring file, and then copy the files to the/etc/SWIFT directory of each node in the cluster, all the server processes that need to use the ring will check the modification time mtime of the ring file every 15 seconds (default value). If the modification time is different from that in the memory, reload the ring file to the memory.
Example
Now add a storage node node4 and use it as zone5 with the same weight as devcie. Therefore, the number of partitions on each storage node is 52428.8. 13107.2 partitions need to be randomly removed from each storage node to the collection list, and then the parttion needs to be reassigned to node4. When replica with partition is reassigned, the redistribution time is recorded. The use of min_part_hours in the ringbuilder class is limited within the specified time. The same partition will not be moved twice.
Since the partition used for redistribution is random, the rebalacne process cannot rebalance the ring perfectly once. To achieve a balanced ring, the rebalacne process is repeatedly executed until it is near perfect (less than 1%) or when the rebalacne increase reaches a minimum of 1%.
First, remove the old ring file:
Rm-F account. Builder account.ring.gz backups/account. Builder backups/account.ring.gz
.......
Then, rebalance the ring file:
Swift-ring-builder account. Builder create 18 3 1
Swift-ring-builder account. Builder add z1-192.168.1.50: 6002/SDC 100
Swift-ring-builder account. Builder add z2-192.168.1.51: 6002/SDC 100
Swift-ring-builder account. Builder add z3-192.168.1.52: 6002/SDC 100
Swift-ring-builder account. Builder add z4-192.168.1.54: 6002/SDC 100
Swift-ring-builder account. Builder add z5-192.168.1.53: 6002/SDC 100
Swift-ring-builder account. Builder rebalance
Swift-ring-builder container. Builder create 18 3 1
Swift-ring-builder container. Builder add z1-192.168.1.50: 6001/SDC 100
Swift-ring-builder container. Builder add z2-192.168.1.51: 6001/SDC 100
Swift-ring-builder container. Builder add z3-192.168.1.52: 6001/SDC 100
Swift-ring-builder container. Builder add z4-192.168.1.54: 6001/SDC 100
Swift-ring-builder container. Builder add z5-192.168.1.53: 6001/SDC 100
Swift-ring-builder container. Builder rebalance
Swift-ring-builder object. Builder create 18 3 1
Swift-ring-builder object. Builder add z1-192.168.1.50: 6000/SDC 100
Swift-ring-builder object. Builder add z2-192.168.1.51: 6000/SDC 100
Swift-ring-builder object. Builder add z3-192.168.1.52: 6000/SDC 100
Swift-ring-builder object. Builder add z4-192.168.1.54: 6000/SDC 100
Swift-ring-builder object. Builder add z5-192.168.1.53: 6000/SDC 100
Swift-ring-builder object. Builder rebalance
At the end, copy account.ring.gz?container.ring.gz?object.ring.gz to the/etc/SWIFT directory of each node in the cluster. In this way, we have completed the rebalance of the ring ).
References: http://docs.openstack.org/developer/swift/index.htm
Cowhide: http://www.cnblogs.com/yuxc/archive/2012/06/28/2568584.html