[PYTHON] Utilisez le problème d'emballage des bacs pour réduire les frais d'utilisation du cloud

Optimisation de l'utilisation du cloud à l'aide de problèmes d'emballage

Désormais, lorsque vous utilisez un cloud tel qu'AWS, Azure ou GCP, vous vous demandez peut-être quelle application doit être répertoriée sur une machine virtuelle de quelle taille pour plus d'efficacité. Étant donné que l'utilisation du processeur, de la mémoire et du disque de l'application sont connues, dans quelle taille de machine virtuelle l'application doit-elle être placée, si elle doit être colocalisée, distribuée, etc. Il y a. Il semble que les ingénieurs ayant une longue histoire d'utilisation du cloud sauront quelle taille choisir en fonction de leur expérience. Cependant, cette fois j'ai changé un peu d'approche et je me suis demandé si je pouvais trouver une solution comme problème d'optimisation.

Par exemple, dans les situations suivantes, quelle taille d'application doit être placée dans quelle taille de machine virtuelle pour être efficace?

1.png

Tout d'abord

Le problème d'optimisation me paraissait intéressant, donc après avoir étudié, j'ai pensé à un problème qui m'était familier. Étant donné que l'historique des problèmes d'optimisation est d'une semaine, veuillez signaler toute erreur ou tout conseil.

Les livres suivants ont été utilisés pour étudier. [Optimisation / Analyse statistique / Machine Learning pour les praticiens de l'analyse commerciale en langage Python](https://www.amazon.co.jp/Python%E8%A8%80%E8%AA%9E%E3%81] % AB% E3% 82% 88% E3% 82% 8B% E3% 83% 93% E3% 82% B8% E3% 83% 8D% E3% 82% B9% E3% 82% A2% E3% 83% 8A % E3% 83% AA% E3% 83% 86% E3% 82% A3% E3% 82% AF% E3% 82% B9-% E5% AE% 9F% E5% 8B% 99% E5% AE% B6% E3% 81% AE% E3% 81% 9F% E3% 82% 81% E3% 81% AE% E6% 9C% 80% E9% 81% A9% E5% 8C% 96% E3% 83% BB% E7% B5% B1% E8% A8% 88% E8% A7% A3% E6% 9E% 90% E3% 83% BB% E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92-% E4% B9% 85% E4% BF% 9D-% E5% B9% B9% E9% 9B% 84 / dp / 4764905167 / ref = sr_1_1? Ie = UTF8 & qid = 1495359888 & sr = 8-1 & mots-clés = python +% E3% 83% 93% E3% 82% B8% E3% 83% 8D% E3% 82% B9% E3% 83% BB% E3% 82% A2% E3% 83% 8A% E3% 83% AA% E3% 83% 86% E3% 82% A3% E3% 82% AF% E3% 82% B9)

Problème de réglage

Cette fois, à la suite de la liste du nombre d'applications requis sur la machine virtuelle dans le cloud, je voudrais trouver la configuration avec le coût le plus bas en tant que problème d'emballage de bac.

Le problème de l'emballage en bac est un problème d'optimisation de combinaison qui trouve le nombre minimum de conteneurs requis lors de l'emballage d'un conteneur (boîte, bouteille, conteneur) avec des bagages (le poids et le nombre sont fixes). Par exemple, lorsque vous déménagez, vous pouvez emballer vos bagages dans du carton, mais la solution est de minimiser le nombre de cartons.

2.png

Si vous souhaitez emballer vos bagages dans un carton, tenez compte du volume et du poids des bagages par rapport au volume (largeur x longueur x hauteur) et à la capacité de charge de la boîte en carton. Quand j'ai vu cela, j'ai senti que je pouvais optimiser l'utilisation des machines virtuelles dans le cloud en remplaçant les bagages en tant qu'application, le carton en tant que machine virtuelle, et en remplaçant le volume et le poids par le processeur, la RAM, le disque et le coût. C'est le début.

environnement

Je voudrais résoudre le problème d'optimisation avec Python. Python fournit une variété de bibliothèques utiles pour résoudre les problèmes d'optimisation, qui sont expliqués en détail ici. Python dans l'optimisation

Cette fois, j'ai utilisé openopt avec Python 3.5 (Anaconda). Le système d'exploitation est CentOS 7.3. Openopt est une bibliothèque qui crée des modèles pour l'optimisation mathématique.

Voici comment installer openopt dans cet environnement:

conda install --channel https://conda.anaconda.org/cachemeorg funcdesigner openopt
pip install cvxopt
pip install glpk

Choses à faire

Cette fois, nous diviserons l'application en trois types. Petites applications, applications moyennes, grandes applications. L'utilisation de chaque ressource est la suivante.

Petite application Application moyenne Grande application
CPU: 0.2 CPU: 0.5 CPU: 2.4
RAM: 256MB RAM: 512MB RAM: 2048MB
DISK: 1GB DISK: 10GB DISK: 40GB

Utilisez le problème d'emballage de bac pour savoir laquelle des tailles d'instance EC2 suivantes est la moins chère à emballer.

M4.4xlarge R3.2xlarge C4.2xlarge
CPU: 16vCPU CPU: 8vCPU CPU: 8vCPU
RAM: 64GB RAM: 61GB RAM: 15GB
Disk: 100GB Disk: 100GB Disk: 100GB
$1.032 / hour $0.798 / hour $0.504 / hour

Le prix unitaire est le prix lors de l'utilisation d'une instance Linux à la demande dans la région de Tokyo à partir d'aujourd'hui (21 mai 2017). Référence De plus, le coût du disque (EBS) n'est pas inclus.

programme

Le programme complet est ici.

# import openopt
from openopt import *

#Définissez le nombre d'applications petites, moyennes et grandes.
small_num = 20
med_num = 12
large_num = 9

apps = []

#Utilisez les ressources de chaque dict d'application et ajoutez-le à la liste.
for i in range(small_num):
    small_app = {
        'name': 'small%d' % i,
        'cpu': 0.2,
        'mem': 256,
        'disk': 1
        }
    apps.append(small_app)

for i in range(med_num):
    med_app = {
        'name': 'medium%d' % i,
        'cpu': 0.5,
        'mem': 512,
        'disk': 10
        }
    apps.append(med_app)
    
for i in range(large_num):
    large_app = {
        'name': 'large%d' % i,
        'cpu': 2.4,
        'mem': 2048,
        'disk': 40
        }
    apps.append(large_app)


#Définit la taille de l'instance AWS EC2.
#Chaque ressource est multipliée par 9 car le système d'exploitation compte 10 ressources%C'est parce que l'on suppose que
instance_sizes = [
    {
        'name': 'm4.x4large',
        'cost': 1.032 * 24 * 30,
        'size': {
            'cpu': 16 * 0.9,
            'mem': 64 * 1024 * 0.9, 
            'disk': 1000 * 0.9
        }
    },
    {
        'name': 'r3.2xlarge',
        'cost': 0.798 * 24 * 30,
        'size': {
            'cpu': 8 * 0.9,
            'mem': 61 * 1024 * 0.9, 
            'disk': 1000 * 0.9
        }
    },
    {
        'name': 'c4.2xlarge',
        'cost': 0.504 * 24 * 30,
        'size': {
            'cpu': 8 * 0.9,
            'mem': 15 * 1024 * 0.9, 
            'disk': 1000 * 0.9
        }
    }
]

#C'est un emballage poubelle.
#Nous utilisons une fonction appelée BPP de openopt.
def bin_pack_instance(apps, instance_size):
    cost = instance_size['cost']    
    p = BPP(apps, instance_size['size'], goal = 'min')
    r = p.solve('glpk', iprint = 0)
    instances = len(r.xf)
    total_cost = instances * cost
    return r, instances, total_cost

#Je le ferai.
#Bac d'emballage pour chaque taille d'instance et trouvez la moins chère.
if __name__ == '__main__':
    list_cost = []
    for instance in instance_sizes:
        r, instances, total_cost = bin_pack_instance(apps, instance)
        list_cost.append({'instance': instance['name'], 'total_cost': total_cost})

        print("\r") 
        print("Bin packing for : {0}".format(instance['name']))
        print("Total number of apps is " + str(len(apps)))
        print("Total {0} instance used is {1}".format(instance['name'], instances))
        print("Total cost is {0}".format(total_cost))

        for i,s in enumerate(r.xf):
            print ("Instance {0} contains {1} apps".format(i, len(s)))
            print("\t CPU: {0}vCPU\t RAM: {1}MB\t Disk: {2}GB"
                  .format(r.values['cpu'][i], r.values['mem'][i], r.values['disk'][i]))
            print("\t Contains: {0}".format(r.xf[i]))

        print("\r")  
    
    print("Result: {0}".format(list_cost))

Le résultat est le suivant.

------------------------- OpenOpt 0.5625 -------------------------
problem: unnamed   type: MILP    goal: min
solver: glpk
  iter  objFunVal  log10(maxResidual)  
    0  0.000e+00               0.00 
    1  0.000e+00            -100.00 
istop: 1000 (optimal)
Solver:   Time Elapsed = 0.12 	CPU Time Elapsed = 0.12
objFuncValue: 3 (feasible, MaxResidual = 0)

Bin packing for : m4.x4large
Total number of apps is 41
Total m4.x4large instance used is 3
Total cost is 2229.12
Instance 0 contains 18 apps
	 CPU: 14.200000000000001vCPU	 RAM: 13312.0MB	 Disk: 228.0GB
	 Contains: ('small0', 'small3', 'small4', 'small5', 'small6', 'small7', 'small8', 'small13', 'medium0', 'medium1', 'medium2', 'medium3', 'medium4', 'medium5', 'large3', 'large4', 'large6', 'large7')
Instance 1 contains 17 apps
	 CPU: 14.4vCPU	 RAM: 13312.0MB	 Disk: 212.0GB
	 Contains: ('small1', 'small2', 'small9', 'small10', 'small11', 'small12', 'small14', 'small15', 'small16', 'small17', 'small18', 'small19', 'large0', 'large1', 'large2', 'large5', 'large8')
Instance 2 contains 6 apps
	 CPU: 3.0vCPU	 RAM: 3072.0MB	 Disk: 60.0GB
	 Contains: ('medium6', 'medium7', 'medium8', 'medium9', 'medium10', 'medium11')


------------------------- OpenOpt 0.5625 -------------------------
problem: unnamed   type: MILP    goal: min
solver: glpk
  iter  objFunVal  log10(maxResidual)  
    0  0.000e+00               0.00 
    1  0.000e+00            -100.00 
istop: 1000 (optimal)
Solver:   Time Elapsed = 0.24 	CPU Time Elapsed = 0.23
objFuncValue: 5 (feasible, MaxResidual = 0)

Bin packing for : r3.2xlarge
Total number of apps is 41
Total r3.2xlarge instance used is 5
Total cost is 2872.8
Instance 0 contains 3 apps
	 CPU: 7.199999999999999vCPU	 RAM: 6144.0MB	 Disk: 120.0GB
	 Contains: ('large0', 'large4', 'large7')
Instance 1 contains 11 apps
	 CPU: 7.199999999999999vCPU	 RAM: 6912.0MB	 Disk: 107.0GB
	 Contains: ('small5', 'small6', 'small7', 'small8', 'small9', 'small18', 'small19', 'medium0', 'medium1', 'large1', 'large2')
Instance 2 contains 13 apps
	 CPU: 7.0vCPU	 RAM: 6912.0MB	 Disk: 91.0GB
	 Contains: ('small0', 'small1', 'small2', 'small10', 'small11', 'small12', 'small13', 'small14', 'small15', 'small16', 'small17', 'large5', 'large6')
Instance 3 contains 8 apps
	 CPU: 7.199999999999999vCPU	 RAM: 6656.0MB	 Disk: 122.0GB
	 Contains: ('small3', 'small4', 'medium2', 'medium3', 'medium4', 'medium5', 'large3', 'large8')
Instance 4 contains 6 apps
	 CPU: 3.0vCPU	 RAM: 3072.0MB	 Disk: 60.0GB
	 Contains: ('medium6', 'medium7', 'medium8', 'medium9', 'medium10', 'medium11')


------------------------- OpenOpt 0.5625 -------------------------
problem: unnamed   type: MILP    goal: min
solver: glpk
  iter  objFunVal  log10(maxResidual)  
    0  0.000e+00               0.00 
    1  0.000e+00            -100.00 
istop: 1000 (optimal)
Solver:   Time Elapsed = 0.14 	CPU Time Elapsed = 0.14
objFuncValue: 5 (feasible, MaxResidual = 0)

Bin packing for : c4.2xlarge
Total number of apps is 41
Total c4.2xlarge instance used is 5
Total cost is 1814.4
Instance 0 contains 7 apps
	 CPU: 5.4vCPU	 RAM: 5120.0MB	 Disk: 100.0GB
	 Contains: ('medium0', 'medium1', 'medium2', 'medium3', 'medium4', 'medium5', 'large6')
Instance 1 contains 15 apps
	 CPU: 7.0vCPU	 RAM: 7168.0MB	 Disk: 108.0GB
	 Contains: ('small8', 'small9', 'small10', 'small14', 'small16', 'small17', 'small18', 'small19', 'medium6', 'medium7', 'medium8', 'medium9', 'medium10', 'medium11', 'large0')
Instance 2 contains 14 apps
	 CPU: 7.199999999999999vCPU	 RAM: 7168.0MB	 Disk: 92.0GB
	 Contains: ('small0', 'small1', 'small2', 'small3', 'small4', 'small5', 'small6', 'small7', 'small11', 'small12', 'small13', 'small15', 'large3', 'large4')
Instance 3 contains 3 apps
	 CPU: 7.199999999999999vCPU	 RAM: 6144.0MB	 Disk: 120.0GB
	 Contains: ('large1', 'large2', 'large5')
Instance 4 contains 2 apps
	 CPU: 4.8vCPU	 RAM: 4096.0MB	 Disk: 80.0GB
	 Contains: ('large7', 'large8')

Result: [{'instance': 'm4.x4large', 'total_cost': 2229.12}, {'instance': 'r3.2xlarge', 'total_cost': 2872.8}, {'instance': 'c4.2xlarge', 'total_cost': 1814.4}]


Ce sera plus long, mais par conséquent, il semble plus efficace de regrouper c4.2xlarge en 4 unités, ce qui coûte 1814,4 $ par mois.

Impressions

Cette fois, j'ai considéré le placement des candidatures comme un problème d'optimisation. Bien sûr, il existe peu de cas où toutes les applications sont regroupées dans une instance de la même taille, et il y a de nombreux points à considérer lors de l'examen de l'architecture, comme la séparation de sous-réseau. En fait, je voulais calculer une configuration qui mélangeait plusieurs tailles d'instance (c4.2xlarge 3 unités, t2.micro 4 unités, etc.), mais je ne sais pas comment emballer dans plusieurs bacs de tailles différentes, donc cette forme devenu. Ce sera un problème pour le futur. Si vous avez des détails, merci de me le faire savoir.

référence

Utiliser l'optimisation des combinaisons Problème standard d'optimisation combiné et méthode d'exécution Python dans l'optimisation Comment résoudre le problème d'emballage du bac [Optimisation / Analyse statistique / Machine Learning pour les praticiens de l'analyse commerciale en langage Python](https://www.amazon.co.jp/Python%E8%A8%80%E8%AA%9E%E3%81] % AB% E3% 82% 88% E3% 82% 8B% E3% 83% 93% E3% 82% B8% E3% 83% 8D% E3% 82% B9% E3% 82% A2% E3% 83% 8A % E3% 83% AA% E3% 83% 86% E3% 82% A3% E3% 82% AF% E3% 82% B9-% E5% AE% 9F% E5% 8B% 99% E5% AE% B6% E3% 81% AE% E3% 81% 9F% E3% 82% 81% E3% 81% AE% E6% 9C% 80% E9% 81% A9% E5% 8C% 96% E3% 83% BB% E7% B5% B1% E8% A8% 88% E8% A7% A3% E6% 9E% 90% E3% 83% BB% E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92-% E4% B9% 85% E4% BF% 9D-% E5% B9% B9% E9% 9B% 84 / dp / 4764905167 / ref = sr_1_1? Ie = UTF8 & qid = 1495359888 & sr = 8-1 & mots-clés = python +% E3% 83% 93% E3% 82% B8% E3% 83% 8D% E3% 82% B9% E3% 83% BB% E3% 82% A2% E3% 83% 8A% E3% 83% AA% E3% 83% 86% E3% 82% A3% E3% 82% AF% E3% 82% B9) https://github.com/PythonCharmers/OOSuite/blob/master/OpenOpt/openopt/examples/bpp_2.py

Recommended Posts

Utilisez le problème d'emballage des bacs pour réduire les frais d'utilisation du cloud
Comment résoudre le problème d'emballage du bac
Prise en compte de l'approche du problème d'emballage en bac
Comment utiliser l'API Google Cloud Translation
Comment utiliser le générateur
Comment utiliser le décorateur
Comment utiliser la fonction zip
Comment utiliser le module optparse
Comment utiliser le module ConfigParser
Utilisez Rasppie pour résoudre le problème de connexion Wi-Fi mobile insuffisante
Comment utiliser le pipeline Spark ML
[Linux] Comment utiliser la commande echo
Utilisez .flatten () [0] de numpy pour récupérer la valeur
Comment utiliser le débogueur IPython (ipdb)
Comment utiliser l'API Cloud Vision de GCP
3 meilleures façons d'utiliser la commande less
Utilisez linter pour réduire les coûts de révision du code