Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
560
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.12 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. '''
  4. This script writes X MegaByte random data to a number RADOS objects and reads the data again afterwards
  5.  
  6. It sends these statistics towards a InfluxDB so you can plot the latency of your Ceph cluster
  7.  
  8. Author: Wido den Hollander <wido@widodh.nl>
  9. '''
  10.  
  11. import argparse
  12. import uuid
  13. import time
  14. import datetime
  15. import socket
  16. import logging
  17. from influxdb import InfluxDBClient
  18. from rados import Rados, Error
  19.  
  20. logging.basicConfig(level=logging.INFO)
  21. log = logging.getLogger(__name__)
  22.  
  23.  
  24. def random_data(size):
  25. with open('/dev/zero', 'r') as z:
  26. data = z.read(size)
  27.  
  28. return data
  29.  
  30.  
  31. def rados_bench(ceph_conf, pools, rados_id, object_size, num_objects):
  32. try:
  33. r = Rados(conffile=ceph_conf, rados_id=rados_id)
  34. r.conf_set("client_mount_timeout", "10")
  35. r.conf_set("rados_mon_op_timeout", "10")
  36. r.conf_set("rados_osd_op_timeout", "10")
  37. r.connect()
  38. fsid = r.get_fsid()
  39. except:
  40. raise
  41.  
  42. stats = dict()
  43.  
  44. for pool in pools:
  45. try:
  46. ioctx = r.open_ioctx(pool)
  47.  
  48. write_total_time = 0
  49. read_total_time = 0
  50.  
  51. i = 0
  52.  
  53. len = object_size * 1024 * 1024
  54. data = random_data(len)
  55.  
  56. while i < num_objects:
  57. obj = str(uuid.uuid4())
  58.  
  59. start_write = time.clock()
  60. ioctx.write_full(obj, data)
  61. write_total_time += (time.clock() - start_write) * 1000
  62.  
  63. start_read = time.clock()
  64. ioctx.read(obj, len)
  65. read_total_time += (time.clock() - start_read) * 1000
  66.  
  67. ioctx.remove_object(obj)
  68. i += 1
  69.  
  70. ioctx.close()
  71.  
  72. stats[pool] = {'write_latency': write_total_time / num_objects,
  73. 'read_latency': read_total_time / num_objects}
  74. except Error as exc:
  75. log.error(exc)
  76. continue
  77.  
  78. r.shutdown()
  79.  
  80. return {'fsid': fsid, 'pools': stats}
  81.  
  82.  
  83. def send_to_influx(host, port, user, password, db, ssl, verify, stats):
  84. influx = InfluxDBClient(host=host, port=port, username=user,
  85. password=password, database=db, ssl=ssl,
  86. verify_ssl=verify)
  87. influx.write_points(data)
  88.  
  89.  
  90. def gen_influx_data(stats, now):
  91. data = list()
  92. for pool, values in stats['pools'].items():
  93. entry = dict()
  94. entry['measurement'] = 'ceph_pool_latency'
  95. entry['tags'] = {'pool': pool, 'ceph_fsid': stats['fsid']}
  96. entry['time'] = now
  97. entry['fields'] = {'write_latency': values['write_latency'],
  98. 'read_latency': values['read_latency']}
  99. data.append(entry)
  100.  
  101. return data
  102.  
  103.  
  104. if __name__ == '__main__':
  105. parser = argparse.ArgumentParser(description='Measure Ceph RADOS latency and send to Influx')
  106. parser.add_argument("--host", action="store", dest="influx_host", default="localhost", help="The Influx host")
  107. parser.add_argument("--port", action="store", dest="influx_port", type=int, default=8086, help="The Influx port")
  108. parser.add_argument("--user", action="store", dest="influx_user", help="The Influx port")
  109. parser.add_argument("--password", action="store", dest="influx_password", help="The Influx port")
  110. parser.add_argument("--db", action="store", dest="influx_db", default="ceph", help="The InfluxDB database")
  111. parser.add_argument("--ssl", action="store_true", dest="influx_ssl", help="Enable SSL for Influx")
  112. parser.add_argument("--verify", action="store_true", dest="influx_verify", help="Verify SSL")
  113.  
  114. parser.add_argument("-n", "--dry", action="store_true", dest="dry", help="Dry run, do not send to Influx")
  115.  
  116. parser.add_argument("--size", action="store", dest="object_size", type=int, default=1, help="The object size in MegaBytes")
  117. parser.add_argument("--num", action="store", dest="num_objects", type=int, default=10, help="The number of objects to write and read")
  118. parser.add_argument("-p", "--pool", action="append", dest="rados_pool", required=True, help="The RADOS pool to write in. Specify multiple times for more pools")
  119.  
  120. parser.add_argument("-c", "--conf", action="store", dest="ceph_conf", default="/etc/ceph/ceph.conf", help="The ceph configuration file")
  121. parser.add_argument("-i", "--id", action="store", dest="rados_id", default="admin", help="Cephx ID to use")
  122.  
  123. parser.add_argument("-d", "--debug", action="store_true", dest="debug", help="Debug logging")
  124. conf = parser.parse_args()
  125.  
  126. try:
  127. stats = rados_bench(ceph_conf=conf.ceph_conf, pools=conf.rados_pool,
  128. rados_id=conf.rados_id,
  129. object_size=conf.object_size,
  130. num_objects=conf.num_objects)
  131.  
  132. data = gen_influx_data(stats, datetime.datetime.utcnow().isoformat())
  133.  
  134. if not conf.dry:
  135. log.debug(data)
  136. send_to_influx(conf.influx_host, conf.influx_port, conf.influx_user,
  137. conf.influx_password, conf.influx_db, conf.influx_ssl,
  138. conf.influx_verify, data)
  139. else:
  140. log.info(data)
  141.  
  142. except Exception as e:
  143. raise
  144. log.error(e)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement