Swift源碼解析之添加裝置到Ring

來源:互聯網
上載者:User
執行swift-ring-builder的add命令添加裝置到Ring中,與create命令類似,add命令由swift.cli.ringbuilder.Commands類add()函數完成
# swift/cli/ringbuilder.py    def add():        #_parse_add_values()解析參數,並返回一個device的列表,然後檢查新添加的device是否在devs列表中,        #如果沒有,則通過RingBuild類的add_dev()函數將新的device添加到Ring中        if len(argv) < 5 or len(argv) % 2 != 1:            print Commands.add.__doc__.strip()            exit(EXIT_ERROR)        for new_dev in _parse_add_values(argv[3:]):            for dev in builder.devs:                if dev is None:                    continue                if dev['ip'] == new_dev['ip'] and \                        dev['port'] == new_dev['port'] and \                        dev['device'] == new_dev['device']:                    print 'Device %d already uses %s:%d/%s.' % \                          (dev['id'], dev['ip'], dev['port'], dev['device'])                    print "The on-disk ring builder is unchanged.\n"                    exit(EXIT_ERROR)            dev_id = builder.add_dev(new_dev)            print('Device %s with %s weight got id %s' %                  (format_device(new_dev), new_dev['weight'], dev_id))        builder.save(argv[1])        exit(EXIT_SUCCESS)
最終使用第一步中建立的swift.common.ring.builder.RingBuilder類執行個體的add_dev()函數完成裝置的添加。
# swift/common/ring/builder.pydef add_dev(self, dev):        """        將一個裝置添加到ring裡面去。這個裝置的dict資料至少需要包含以下的索引值(key)        ====== ===============================================================        id 裝置的唯一編號(類型為整數),如果"id" key在dict中沒有指定,則預設該裝置的id為系統中下一個可用的id號        weight 這個裝置的權重。這個權重值用來暗示會有多少個partition分配到這個裝置上來。        region 裝置所在的region號(類型為整數)。        zone 裝置所在的zone號(類型為整數)。一個partition會被儘可能地發配到分布在不同的(region,zone)的裝置上去。        ip 裝置的ip地址        port 該裝置的tcp連接埠        device 該裝置的名字(譬如,sdb1)        meta 中繼資料,用於儲存使用者自訂資料,譬如裝置上線時間,硬體描述,等等        ====== ===============================================================        注意::添加一個裝置不會立即導致rebalance,因為使用者可能想在添加多個裝置之後統一做rebalance        """        if 'id' not in dev:            dev['id'] = 0            if self.devs:                dev['id'] = max(d['id'] for d in self.devs if d) + 1        if dev['id'] < len(self.devs) and self.devs[dev['id']] is not None:            raise exceptions.DuplicateDeviceError(                'Duplicate device id: %d' % dev['id'])        # Add holes to self.devs to ensure self.devs[dev['id']] will be the dev        while dev['id'] >= len(self.devs):            self.devs.append(None)        dev['weight'] = float(dev['weight'])        dev['parts'] = 0        self.devs[dev['id']] = dev        #根據裝置的weight計算應該接納的parttion個數        self._set_parts_wanted()        self.devs_changed = True        self.version += 1        return dev['id']
這個函數先計算所要添加device的ID,ID值可以不是連續的,裝置表中間允許空洞的存在。然後將裝置加入到Ring的裝置表中,最後設定相關flag,devs_changed表示裝置表有變化,需要rebalance。 這個函數返回後,swift.cli.ringbuilder.Commands類的add()函數會再次調用RingBuild類的save()函數,將更新過的Ring資訊寫到builder檔案中去。 到此添加裝置到Ring的步驟完成。
相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.