def printParms(fmt, disk, raid, rados, site, multi): """ print out the parameters associated with a test """ if disk is not None: print "Disk Modeling Parameters" print " size: %10s" % printSize(disk.size) print(" FIT rate: %10d (MTBF = %s)" % (disk.fits, printTime(mttf(disk.fits)))) print " NRE rate: %10.1E" % disk.nre if raid is not None: print "RAID parameters" print " replace: %16s" % printTime(raid.delay) if raid.speed > 0: print(" recovery rate: %7s/s (%s)" % (printSize(raid.speed), printTime(raid.rebuild_time()))) print " NRE model: %10s" % raid.nre_model print " object size: %10s" % printSize(raid.objsize) if rados is not None: print "RADOS parameters" print " auto mark-out: %14s" % printTime(rados.delay) print(" recovery rate: %8s/s (%s/drive)" % (printSize(rados.speed), printTime(rados.rebuild_time(rados.speed)))) print " osd fullness: %7d%%" % (rados.full * 100) print " declustering: %7d PG/OSD" % rados.pgs print " NRE model: %10s" % rados.nre_model print " object size: %7s" % \ printSize(rados.objsize, unit=1024) print " stripe length:%7d" % rados.stripe if site is not None: print "Site parameters" s = 0 if multi is None else multi.sites if site.fits == 0: print " disasters: IGNORED" else: tf = mttf(site.fits) print(" disaster rate: %12s (%d FITS)" % (printTime(tf), site.fits)) if site.replace == 0: print " site recovery: NEVER" else: print " site recovery: %11s" % printTime(site.replace) if multi is not None: print(" recovery rate: %8s/s (%s/PG)" % (printSize(multi.speed), printTime(multi.rados.rebuild_time(multi.speed)))) if multi.latency == 0: print " replication: synchronous" else: print(" replication: asynchronous (%s delay)" % (fmt.printTime(multi.latency)))
def run(models, columns="", verbosity="default", capacity=1*PiB, period=1*YEAR): """ execute a single model and print out the results models -- list of models to be run columns -- what optional columns to include verbosity -- what kind of output we want capacity -- total system capacity (bytes) period -- modeled time period (hours) """ # figure out what optional fields to include showTr = False # FIX get from columns showBW = False # FIX get from columns # define the column headings heads = [ "configuration", "<p,s>/PiB", "durability", "Ploss" ] legends = [ "configuration being modeled", "<primaries, secondaries> per petabyte", "probability of object survival*", "probability of loss*", ] # consider the optional fields if showBW: heads.append("BW(recov)") legends.append("peak recovery bandwidth") if showTr: heads.append("T(recov)") legends.append("max detect/recovery time") # figure out the longest description maxlen = len(heads[0]) for m in models: l = len(m.descr) if l > maxlen: maxlen = l format = ColumnPrint(heads, maxdesc=maxlen) # figure out what output he wants parm1 = True # basic parameters at front descr = True # descriptions of columns headings = True # column headings parms = True # all parameters for every model debug = False # diagnostic output if verbosity == "parameters": # per-test parameters parm1 = False descr = False elif verbosity == "headings": # output and headings parm1 = False parms = False descr = False elif verbosity == "data": # minimal - just the output parm1 = False parms = False descr = False headings = False elif verbosity == "all": # pretty much everyting debug = True parm1 = False elif verbosity == "debug": # debug only debug = True headings = False parm1 = False parms = False descr = False else: parms = False # print out basic parameters (assumed not to change) if parm1: printParms(models[0], None, None) # print out column legends if descr: print "" print "Column legends:" s = printTime(period) i = 1 while i <= len(legends): l = legends[i - 1] if l.endswith('*'): print "\t%d %s (per %s)" % (i, l, s) else: print "\t%d %s" % (i, l) i += 1 # print out column headings if headings: format.printHeadings() for m in models: # compute sizes and rates sizes = Sizes(m, capacity, debug) rates = Rates(m, debug) # print out the model parameters if parms: printParms(m, sizes, rates) # compute and print the reliability results = Results(m, sizes, rates, period, debug) s = list() s.append(m.descr) if m.symmetric: s.append("<%d>" % (sizes.n_primary)) else: s.append("<%d,%d>" % (sizes.n_primary, sizes.n_secondary)) s.append(printDurability(results.durability)) s.append(printProbability(results.p_loss)) bw = max(results.bw_sfail, results.bw_pfail) if showBW: s.append("n/a" if bw == 0 else printSize(bw, 1000) + "/s") if showTr: s.append("n/a" if bw == 0 else printFloat(results.Trecov)+"s") format.printLine(s)
def Run(tests, period=YEAR, verbosity="all"): """ run and report a set of specified simulations tests -- actual list of simulations to run (print a header line for each None test) period -- simulation period verbosity -- output options """ # column headings heads = ("storage", "durability", "PL(site)", "PL(copies)", "PL(NRE)", "PL(rep)", "loss/PiB") # column descriptions legends = [ "storage unit/configuration being modeled", "probability of object survival*", "probability of loss due to site failures*", "probability of loss due to drive failures*", "probability of loss due to NREs during recovery*", "probability of loss due to replication failure*", "expected data loss per Petabyte*" ] # use the headings to generate a format format = ColumnPrint(heads, maxdesc=20) # figure out what output he wants headings = True parms = True descr = True if verbosity == "parameters": descr = False elif verbosity == "headings": parms = False descr = False elif verbosity == "data only": parms = False descr = False headings = False # introspect the tests to find the disk/raid/rados parameters disk = None raid = None rados = None site = None multi = None for t in tests: c = t.__class__.__name__ if disk is None and "Disk" in c: disk = t if raid is None and c.startswith("RAID"): raid = t if rados is None and c.startswith("RADOS"): rados = t if site is None and c.startswith("Site"): site = t if multi is None and c.startswith("MultiSite"): multi = t # find elements that only exist beneath others if site is None and multi is not None: site = multi.site if rados is None and multi is not None: rados = multi.rados if disk is None and rados is not None: disk = rados.disk if disk is None and raid is not None: disk = raid.disk if parms: printParms(format, disk, raid, rados, site, multi) if descr: print "" print "Column legends" s = printTime(period) i = 1 while i <= len(legends): l = legends[i - 1] if l.endswith('*'): print "\t%d %s (per %s)" % (i, l, s) else: print "\t%d %s" % (i, l) i += 1 if headings: format.printHeadings() # expected data loss after drive failures for t in tests: if t is None: format.printHeadings() continue # calculate the renderable reliabilities and durability s = list() t.compute(period=period) s.append(t.description) # description s.append(printDurability(t.dur)) # durability s.append(printProbability(t.P_site)) # P(site failure) s.append(printProbability(t.P_drive)) # P(drive failure) s.append(printProbability(t.P_nre)) # P(NRE on recovery) s.append(printProbability(t.P_rep)) # P(replication failure) l = (t.P_site * t.L_site) + (t.P_drive * t.L_drive) +\ (t.P_nre * t.L_nre) + (t.P_rep * t.L_rep) s.append(printExp(l * PiB / t.rawsize)) # expected loss/PiB format.printLine(s)