Architecture overview

This page describes Perforator's architecture.

Intro

Perforator consists of several components. There are four different kinds of components:

  1. Perforator agent which is running on each node of the profiled cluster
  2. A few microservices to collect, store, analyze, and symbolize profiles & executable files from the agents. We run our microservices inside the same cluster Perforator profiles.
  3. A web-based user interface.
  4. A set of databases: ClickHouse to store profile metadata, PostgreSQL to store binary metadata, and S3-compatible store to store raw profiles and binaries.

Such design has been proven to be effective enough to scale to tens of thousands of nodes and petabytes of profiles.

High-level schema

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO19W1NcdTAwMWJLsu77+lx1MDAxNYT3yzlcdTAwMTFDTVVlXbL2XHUwMDFid7C5Y1x1MDAwM+bMXHUwMDBlh0BcdTAwMDJcdTAwMDRCXHUwMDAySVxcJ+a/n0xhULf6KiGB2MvMhJeNpFJ1d2V+X97//dfMzJfu43Xty3/PfKk9nFRcdTAwMWH1arty/+VcdTAwMWb8+7tau1NvNekl3ft3p3XbPum987zbve789z//2f+EOGldPX+q1qhd1ZrdXHUwMDBlve//0b9nZv7d+zPyPe3aSbfSPGvUelx1MDAxZui91P8qQD/4281Ws/e1yliURir1+oZ6s1p74CWPXHUwMDE19Fx1MDAxN6t3XHUwMDE2aVx1MDAxM91alV45rTQ6tf4r/Ksvemtzq75f31hatYdcdTAwMDeqsfn1znRs/+On9UZjr/vYeL7Sysn5bTuy00633bqsXHUwMDFk1Kvd85dcdTAwMWJcdTAwMTP5/evnqpXOOW3g9eV26/bsvFnrdGJcdTAwMWZqXVdO6t1HvjYpX3/7fG/+e6b/XHUwMDFivkaltFx1MDAxNlx1MDAwMej6LWqkP8Lry7yAXHUwMDBlKJRSwdBrXmlv3cDWXHUwMDE2Wo1Wm7f2X6rG/+vv7bhycnlGXHUwMDFibFb77zk9rZ2E0H/P/e9cdTAwMGJGq4VxJlx1MDAxOO+lQlx1MDAxNezrO85r9bPzLr3F2iCMtVxug0ZcdTAwMTOg/zg7td4jUbRFR1x1MDAxYrT9V/jbr9eqvTPzP/1cdTAwMDfRrlxc1db4I83bRiN6K5vV37fy5Wz1T1x1MDAxN/z+zX/6l8fvX4qcyv433F5XK8/nhO6ZXHUwMDA362VwQffvXFyj3rxcdTAwMWP8+kbr5LJ/tP6KfFfioHdrXHUwMDBm3bQzbiNcdTAwMGZ78IxcdTAwMDN47YJcbqmHfK78IW9tL6x3T89cdTAwMWV+fd99gDO8Pqjb/a1PcMjBXHUwMDBirzXQXyT9J8RcdTAwMGY5/VpIUCE4a9FcdTAwMWHl33LGu+1Ks3NdadOxSJ5zjUFY51x1MDAxMLTxiCaic17PuddcdTAwMDJtQCVpI0Y5rVx1MDAwNlx1MDAwZrpHpbz1Jrz9nMdeKHmggVx1MDAxNIG2lu/XXHUwMDEwXHUwMDA3ur+rVrO7V3/iZ2RRaPRo0Fx1MDAwMCjQwcfetFxcuao3+Ong6697XHUwMDA3n27xXq1N53vmv9SX2EtzjfpZs4dcdTAwMDS9W1x1MDAxOZWFbp1cdTAwMTDl9fVu67r/6lx0fVel3qy1k7eqRVx1MDAwYtWblcb37O+t3HZbu7XO81x1MDAwNXXbt7XoPamtvjxUJbTNlelcXPAy0lx1MDAwZf72RbBcdTAwMTFcdTAwMTQpw1x1MDAxMNHaXHUwMDExuV4oL9fVo5tfa1fzjb3qwuzl7df9pcfducVcZrnutFxinKdBqrXzXHUwMDAyXGZ4XHUwMDAzJpBuc/27xFx1MDAwYlx1MDAxOFx1MDAxZFx1MDAwNL2EqOiQWU2vZ4p1jU4zqFwi6DpcdCcp0EVoJIwnlaK9RrBcdTAwMWH6X/Mq08pcdTAwMDBhXHUwMDE3KWDPeyGoTYCXU8FcdTAwMDfp9Fx1MDAxOIR6JPB6/Uz/01mIXHUwMDEzOTVH35srj1x1MDAxYngpT7avcefxpvbt4Lj65fV9//lH+rLPXHUwMDFmvl5wuytbu9eX7vzX9txWOLxUqz/j3/Ly/ZV2u3VcdTAwMWZZ9/ffclx1MDAxMJdoRHBcdTAwMTNHXFzwKkswlZL01K1OXHUwMDE1zMXygpl+i99cdTAwMGZw1WiiXHRSXG7QkuWCRFx1MDAwMrWJi6ZHXHUwMDExvNQgjddG6zdcdTAwMDFutmQqXHUwMDE0llA9XHUwMDA0JOlHiUnBNElJJGiV0iHat0vix8JrRFx1MDAxMVx1MDAxNeDpwlx1MDAwYlx1MDAwNM7MZSDqXHRtutbOgdSrerVcdTAwMWFcdTAwMDWvOKpcdTAwMTbByyDQpm7onaA2U6KNday6ZapEL5WX6Pmn9tbiWXvePlx1MDAxZT+Eo6VfWGnOb0871DpcdTAwMGKCLDAnSYycM66/TI9AeydI2JUjXHUwMDE4Rlx1MDAxMnY7sLMpQlpSXHUwMDA2aFx1MDAxMTx8KqB9uvx6d7BcdTAwMDQr679mL/31Tfvr/M1cdTAwMWSWXHUwMDA12sVZu3P2tGh3XHUwMDE2t7u3t1eLzVx1MDAxZjvdtfFcdTAwMDEt2TIyKorvXHK0dOy0XHJ0ONPkcrm8XFym3+OpR1qHTiBxXHUwMDFkqYM2gajwXHUwMDAwXHS2gswrq9AqXHUwMDEyXHUwMDFiXHUwMDFiXHUwMDAx4vFCrVx1MDAxNyjpXHUwMDA3pGVcdTAwMDQtXHUwMDA3tejZ96ZwXGZcdTAwMWWbz1x1MDAwN7XzXHUwMDEzgtpcdTAwMDJ4yYba+feGWsx2V0mj0evgU91VK+VlemXv7nL+e5jD6q+FZntz9Ydebu9OPdaCXHUwMDE2htQqmYNk4qKKY61zWiA69IRynjA3W6A/XHUwMDFja50hUmDkOKj0O2JtdXG/snlcdTAwMDdrXHUwMDA358eVn7a9iOrch7JY2+2a5U6n2713i1dn+51cdTAwMWK7X7+oj1x1MDAwZmuNVVx1MDAxM8daeqRZcqkloqHjXHUwMDEwIE0uV4dwN6Xe4+nHWmdcdTAwMDWRYC01yZ3CiIOBXHUwMDE38EpcdTAwMGKlQJO962TwenBn47NqJXqyalx0vIB2UVxuap1cbvRcXI3+W0LtwoSgtlx1MDAwMF2yoXbhnaHWukyodVx1MDAxY/cwXHUwMDBlUiV6rbxEV45cdTAwMWZv9y5cdTAwMTaOKvurT1x1MDAwZubpXGbc1dr1tCOt8kFcdTAwMDRcdTAwMWRcdTAwMWNcdTAwMDYjncdcdTAwMDHuTJxa+EBcdTAwMDdcdTAwMTeIijjnc0KfXHUwMDA0gSc6X54rtoqnp5PyXHUwMDFmXHUwMDFiyca5VVx1MDAxZlx1MDAxNfxcdTAwMWNccmpcdTAwMGbuzenR3bZZqm+uf13Z/XWkjlvX71x1MDAwMLW5677BXFzOXfdccv7u3HVcdTAwMWJf8YdeW9g/2by+OnrcgMavi4fLMVCOns5cdTAwMDZcdTAwMTNsxNkzqcg14OBvI+Z9ICsxpEeuv5ZXUOlnbeopXHUwMDA3sVx0QbzDIdO/YEM8xkVmgCDbXtKD0mBcdTAwMWROxrpXIYVkhP5GfyshsMZIXHUwMDA19m/kOd+utU9b7Uq31f5Xc+4sXHUwMDE28lx1MDAxZivTKEDXQaaRs61x8Y1nVZJcIstoMl114KzVOuhUUf5WXpTzNf/UJqFcdTAwMTi0QnpcdTAwMDZqXHUwMDA1xCb8gPVAVj9cdTAwMTn7XHUwMDAxjbWW3qVcdTAwMDZ2NpwoZ7FccqWDINuE/u+1skBcdTAwMGYjhW3QNolcdTAwMTJK6KVjka2RdKI740gzuf5cdTAwMWXHyDZ0MdsoXHUwMDAyLIhcdTAwMWXqslxuoNOttLvzdFwi682z+MZ+51x1MDAxZZZcdTAwMTHFnso4ueVdzkqhXHUwMDE1kFGoXHUwMDFjSmmIYlx1MDAxYVx1MDAxZnnbWeWaL1ZcblLuhHBSKqLizia5Vq1ZLd5VvilcdTAwMTLfXHUwMDE10Pkjw5HgXHUwMDAyXXCRu/W6KzIxXHROrKI/XGagxOSmXHUwMDFhlU53oXV1Ve/S3d9u1Zvdwbvcu51zrCXOa5XEXHUwMDExoIuKvjaoTq55xTix7P9tpi9YvX+8/v1//pH67uwz33s1cdr76/1cdTAwMTX979CaUEmbmXRcdTAwMWFcZt15XHUwMDE1OVx1MDAxMVFVuF5eXHUwMDE15pPVKVaFpOw03Ww6+y5YXHUwMDE1z8dzlswybywn9kiU5m05p5mq0HrOxeN8QFx1MDAxZJC2lGZ3KUEvXHUwMDAxxzQl2WcyaXgpi4okdzJZpyVUYbplUGR47a1cdTAwMWaf11x1MDAwZpdcdTAwMTfPXHUwMDE2u93lo629+4vO7M5Qhlx1MDAwMYlcZkYu+lx1MDAwM/UsKzRJ9rtcZqRtpbWRXGbgIVx1MDAxNFopLZtcdTAwMWZbie/Jkr5BTnJxXGJKhlx1MDAxNCVcdTAwMGJcdTAwMDK8JrVEjFx1MDAwMD1B6udWslnSxD+zSUEqqWTzjmufaqeal8+KRmlcdTAwMTEkfa9Hp9CGuIeHNixcZtKrtG3JNlZCSUSzUtP8q0n9Nlx1MDAwZcPrg71lQ2mwKG7tx74v3Zp7VZyatL92yXybno7Jwk2CcMP+9/5cdTAwMTPIRshBXVx1MDAxOdtGikKzaPtcdTAwMTgwhELrO5xcdTAwMWKN2kl35rrdolx1MDAwN1x1MDAxOHnkQ5uWY7NcdTAwMWJcdTAwMGLoQdJDnXFcdTAwMDVcdTAwMTO3XHUwMDFhlYp4oFx1MDAwN11AXGY2Kt1q3ChPlfL9b1NLlVxi3IREXHUwMDA3gY8oat9cdTAwMTeNXHUwMDFlVVx1MDAwMi9cXOjRJJRcdTAwMWXN21x1MDAxY0CZVMlcYinBo3RcdTAwMDDKO+tT6nOMXHUwMDE3vepcdTAwMWRPXG6VzdfITn5LPCBjg8KJ5Dj/b7FcdTAwMWHpYTvp0JG1SLeTnnff8dk3XHUwMDFhgUxcdTAwMTZiXHUwMDE11lx1MDAxOURcdTAwMDTC09HoTH5WZnxTnFx1MDAxNUtnkPhcZlx1MDAxOanO96Gyz2e8kIpAnkwsyWVY7nPzmcwjzz+zidNeks+UXHUwMDBi10Wq7Fx1MDAxMoVcXLQjqyA9M2arvDZ8anZcdTAwMWHucatyvXxcdTAwMWW2ZeW76txd7U+9NtRcbpQgNUKGIUhrSFxiYtpcdTAwMTAkPTVmoIooXHUwMDFkPbe3+dCyilx1MDAxNb1FgSCVNmBcdTAwMDPR/JRcIi5Latl6TVx1MDAxNqyxwUVkuFx1MDAxZpA3rFxmfZjCakVFtrdcdTAwMWHGtMs96VkxXHUwMDFm57NcdTAwMDFcdTAwMWZcdTAwMDEkWXJcdTAwMTGeXHUwMDFkOeTb5Vx1MDAwZnl7XHUwMDE3oHlwqluXj7vzy5Wlw/XKg/lcdTAwMDSH3DjhWY9cdTAwMTImkV1cdTAwMDXxmFx1MDAwZpDh6OlcdTAwMTZcdTAwMTF/pjehVW9yj1x1MDAxNJcrJk93YYmiJv1EXGLm/pQoRpJcdTAwMDLetURRj5+750KWkzn19YCBU6dSIWunvDQv7Nc37m/vl+Hqx4qdvVm5eHw8np1cdTAwMWGjOUuWUVx1MDAxM3ni2GzgzDE7mJ7thXJKXHUwMDE5a4iBhkhcdTAwMTh86pI5lZKonYVx1Fx1MDAxZL9jisncSnVj7/vy/M+jk63rXHUwMDFm91c7a+tuuWxqxdGSX1289vdzj6vXi0tXi7s3rfPW2LI56Y7qiWdzWp8pmCSWzOhDauHEbnm5TL/F74eyo2VWaK2sIP7OTktAo1XcsDbeXHRA31x1MDAwYtvRmTd2UoVcdTAwMTPsmVYhIFx1MDAxOVg+6lxyy83mXGaSyKdcdTAwMWZHttdnybToJ08uZkDqW31lXHUwMDA18JKdzbn4zlhcdTAwMGLeXGb+9lx1MDAxNWud9lx1MDAxONDrVOa8V16mb5pw1FZd09xdrK5v7i1/PbA7WWXHU4O11pHVxYVcdTAwMTHBk3VcdTAwMDHx/FxucFqYQNjnnKY3yCmuUfTo6PcwXHUwMDE5R9nEkFbWjr7f4K+d891cdTAwMTDun/Yrh1jbmy2LtFx1MDAwZY+2XHUwMDBmvy2uXHUwMDFl3+7VXHUwMDBm3H5cdTAwMWTPgt9cdTAwMWNcdTAwMWbS6mjJwqRqXHUwMDE0TbbXXHUwMDA2jdFcdTAwMGV1epb19/JimX6Pp1x1MDAxZWqdlFwiaC5AcJJs2lx1MDAwMYPWKMVcdTAwMDatV5ZTZehhvbXH1DhrXHUwMDE0teml5si/UVJjXHUwMDFm2ZYmXHUwMDA0tVx1MDAwNeiSXHK1S+9cZrXOZZu1dJ6sYkRJk+mD8jJ9e1tdX6vb/c7T5e3C089vvl2fe5p2qFx1MDAwNZSEYSRJwVx1MDAxMFx1MDAxOVxyXHUwMDAzQSnrRfCoOKxinJJTXFw4XHUwMDAxLrCf9nN1XHUwMDAzWFl62j+73rq4XHUwMDBl9eqRmn1q3Py8XFx8XHUwMDA3pM1d91xytnLuupfW3urvS3dfl89X8LS1+HC4vTE/NmYgybKbeJsgXHUwMDFm6Vx1MDAxOTKYz1x1MDAwMF7TIZapSuSwvFx1MDAxMkk/XHUwMDEyU09cZoxcdTAwMDZB+kNai1x1MDAwMNrHozmOXHUwMDA03HNcdTAwMTiUy06tyql0fofiXHUwMDA241xyXHUwMDE5XHUwMDA1yowh5fmz8ID3Km4oXHUwMDAwwGkqbuCuXlmirKVB4GqpVNv7qLws52voqY1aOamF88SH0DCZXHUwMDFmkGXgZnzaKVx1MDAxMiGpo4GUceap6CCQLHuQhPUkLS4ldqU0XHUwMDExXHUwMDE3zUl/mqHfR4zsXHUwMDE3ym9ccumbXHUwMDEwbfT0XHUwMDE5UnrbXHUwMDE3XHUwMDBid/pKXtz+uNzZumw8ni/6h9PhUnohKFx1MDAxY1x1MDAwNlxmI8+wVFx1MDAxMky+oM9kJOuGflLTTG7Wb+LOlkqCybdFZjKydb2F9E3F0n7pKCU29ZmSYDLliX9mk6LUX++v6H/Tk3rTXHUwMDBmbFx1MDAxZmIyk3o1mVx1MDAxY4JjZpJTudHIuPVBJ0GQja+CJl5B1jumqIk/Sb0vmypM6j1cdTAwMWFcIqnXe29QJkPBPaHOxE0yXHUwMDE0yTKL9l9cdTAwMWZXSi9wVGVcdTAwMTSFNsUpvVx1MDAwNexgilJ6XHUwMDExs5u2IWl241Ijj5XyTCnf5pxapmRcZohe+29CiFx1MDAwMDZcdTAwMWWncGBI6YZeNq/1UZtonEzJWDKtXHUwMDFjXHUwMDE3xHnu6Vx1MDAxOGTfuIpm9JKqVVx1MDAxNuh91jtjXHUwMDEyKb2O13CT8Z6MnND7YtiHyPH7MC6TTNVNpVxysZxfkFx1MDAxNkfjMvkhzJmMTF3XXHUwMDBmXFzEN1x1MDAxNcv57cP75+Qys9lH/vnlxGkvyWZKKMKc5KggpSO7XqVcdTAwMTaCRjNyi3Rhflx1MDAxYpBp1YVKeyWMXCKscEQvNcR73Vx1MDAxMTNcdTAwMTCejFx1MDAwMO1cdTAwMWNqND47ZvtcdTAwMTZdaLVcdTAwMTY2cCfqXoFFpFx1MDAwZeBVXHUwMDE1kpKmjVx1MDAwNOW465fVXHUwMDE4ydN6YT7gyLjVXHUwMDEzaXU3MZtx+6axvvFza3v+YatcdTAwMTlg9Vx1MDAxYi76xbuhbEZDXCJjpqRwguAy8DhcdTAwMDTuoVx1MDAwMFxuo5r2We+hIOuMXGY4hiyPWqvRtOzxhe3c1u1dfXXu9H77dNs/7HmTtqVZ3lx1MDAxM51arZHUiuNs8JTSVEdcZotMWK2t0Vx1MDAwMPC5tSxZZtxmNnjFbS5cZrrop+k+XGJcIuWOKFx1MDAwZf1w2U3RcpmiyT9cdKFcdTAwMWNSYWc2QMxOr/FcbiRoJVNdfM3yyjpd8N5PWY/cjEhcdOKtZOM5XHUwMDBmcmBUlJLcb994kjBuNezMhHx8XFzxxmF8pyRYXHUwMDE17U6VXHUwMDE3x2dfgZHwN8qY277tnCfNvrHaolx1MDAwNZwj4blP3dHkXHJRUqxZXHUwMDEyrY10mrh3am76dXmBzo9STiv7XCLgsYLOppSMUU5cdTAwMGUk5qBcIlNU8lx1MDAxMFx1MDAxM2+4b9OETFHaXHUwMDAzO3p7bTRcXEhcdTAwMGLj095cdTAwMDSA01x1MDAxY8nnTi3Jciok82Ribf0nxr80XHUwMDFki6/Xx7pufrVcdTAwMWZWzlx1MDAxYofH7YWb6eJfhXZutLGQ5vFcdTAwMThkWllcdTAwMGaK9HNKjWjUi45Sy1x1MDAxMVxy3WEoXHUwMDE4Wa9WOeVcdTAwMDJhgOHxgkkjnUxcdTAwMTCevUSI5lx1MDAwMlE1bVx1MDAxM7v6TFx1MDAxY2yW7Fx1MDAxMCGl0YZEhkdcdTAwMDNgjDZcdTAwMTF9XHUwMDEx0JtIKD1XIVx1MDAxNpKw2UxcdO0tNyibY2JhOpOFXHUwMDA14pWkkFQqXHS7Ka+z06Vv2klcdTAwMThcdTAwMGZNXHUwMDEyZMJ4XHUwMDFlVejRXHUwMDBmkjCOwnJcdTAwMTNqhb2Uysn0Tlx1MDAxYY2EeWbq6MzfKJfyXHUwMDFkSFhcdTAwMDH1eF9cdTAwMTJ22qZH/TLq9+VyXuwqlSfSZCZLnybS2lxyMfDB/ry5XGY/L+ftbHV97pu0UNv99i1DpqclmZInxVx0PppcdTAwMWNcdTAwMDdcdTAwMGLaXHUwMDBm1FxiKiC7ilx1MDAxNDmdX8ehVnxcdTAwMTNccsut93X0fEmstSdcYvTEXGJTPGFcYoKrXHUwMDEzgrHsPNZJR5hRwTgr0/Ok+si7+20ndK7syq1S1W250qjc7s7evlCfiauC56m8pCEjR3JcYlUwVriOvZv4iiemzVxcPFjuleJD0edTPvLWXHUwMDE1nbDc0s5wXHUwMDAxOp3HSEtf/om/XG5cdTAwMTJcdTAwMGLXU9xcbpPQglx1MDAwZVxyXHUwMDBmdom0b+JcdTAwMWZ6NUDQzFx0gXl8sVtoVjnh+Vx1MDAxMWJgnlx1MDAxOUnh7K3H+SPPVJQuXHUwMDE2aZuF62nipeC5OaRzwWhcdTAwMTniXHUwMDE0x1x0Xlx1MDAwNoFHVPOgbFu4IFx1MDAwMLtCXHUwMDE07VArMp2Ujq5npECuKqDXPHeFtaZwPWOEIeQ0aIjMStQ+up51Qlx1MDAxMa5pK2kxXHUwMDFmQFx1MDAxNy9cdTAwMTeE5bbaklgg6Vx1MDAxZFx1MDAxZuvW5lhcdTAwMWL53tZcZjF1V3y11lxiXCJ/hlxmRWKHwdrY1XotVFxioDyPaOW4U/FynilcZjtcdTAwMTG191x1MDAwZVwimZ+99azgyKjpjUF2ylx1MDAxNy9cdTAwMTdcdTAwMDRpKsWEl1x1MDAxZa5cdTAwMWZYLXBVXHUwMDE43Vx1MDAwMaBbqJVRZZZD0tiWq1kshIjRzD9IR51cdTAwMWI4XHUwMDE4zmBSXHUwMDAwxes5KViVXHUwMDFhRTKqINYpkJZTgrvHXHUwMDAyrWd4XHUwMDFlUonlsnR4bzmeLERcdTAwMDeEc45cdTAwMTFLKILcxUAoXHUwMDFldYJWgSGrb1KrJUChhDFWv7ptkLbfblx1MDAxM0Ywb1x1MDAxZiA1179//1xmXHUwMDExb2A0mYOZ+bhcdTAwMDNPqk/zLGk3RGCvtfSro3At3NbXL+ZXl1fbR2r+/lx1MDAwZqUpS2mC0KxnwTuuR4E+9e8ne1x1MDAwN0GqmFx1MDAxNDsg55RFupq+ZoSSZNKRzWjW84fUpLw7l5Mowc1cdTAwMTY9XHUwMDExfnpccnywhUpcXIvAgERcdTAwMDKHQPRTxZazQklLeoXQgmcuq0L8y+c3w/NcdTAwMTFFWprb4TpcdTAwMDdAXHUwMDAwI+PdT3tpksR+iKvQe1xm7bJwvTiDsXFNXHRSOCD6XHUwMDAwzj1DRuH1XHUwMDBlXHUwMDEwXHUwMDE4XHUwMDFjoCMgSCej58LMoI0uxHtQgt9cdTAwMTk4zdVYMHE2kuBcdTAwMTaFy5Eu4NJPyZkyZFLEuFdcdTAwMDJcdTAwMWSLVjNWkHFcIjV3XFynI6hDXHUwMDFj7ulgXHUwMDFhWs5cdTAwMTK1MXQjXG5ByypcdTAwMTE9Wyhju/MoJICTTlx1MDAwM909XHUwMDBmxcuBXGLOK2KZOqBcdTAwMDRcdTAwMTdnwkOjfVx1MDAxY1EhvjlcZoJTd5DuXHUwMDFjT782hSyTiFx1MDAxZtE94lZcXEyHOi5cdTAwMTXBXHUwMDEwi1wiaaBT7OmKdeFjdU5cdTAwMDBcdTAwMTmCxFx06c1cdTAwMWP9XHUwMDFlWFxypefuVcZcdTAwMDV6+MWree77RvyRNkZcdTAwMGZcdTAwMDTiq9H5XHUwMDBlxH6JvnPKXHUwMDFjXHUwMDE2XG6YQ2E5YszZQM5oXHUwMDFku2/Bk/KitVx1MDAwMkhcdTAwMGIqXHUwMDE0i2smxvRWXHUwMDFiRJdJrfY5aVLo9eNcdTAwMGUyLf9Ju0Z5moSbu1tLp3rVbuilVlj5debPLuSnp0kkkXTsWXglRFx1MDAwN2mOmyb199WvlCFUI33nnZGkXHUwMDExnPOJ9E+PSPJcclx1MDAxOTVxf2hRwbtnYzTIyGKeXHUwMDEx/3iSxVxm93lcdTAwMTRcXMBcdTAwMGVkXHUwMDBiWlx1MDAwZY1cdTAwMTW7SVx1MDAwNnbvhDRcZrFIjIdUqCukIfHPg1x1MDAxNkjsgJ5cdTAwMGYqXHUwMDA3XHUwMDA0yUN+PHDkmuOfwM3z/ZC7TzhcdTAwMDWGvPfczz5cdTAwMDBcdTAwMTn4znLO2bA3b1gnxsCT46lfr09O+yFvXeBcdTAwMTBRoM9cdTAwMTEwK27CPuSDl0RAjTKe6CTwIOJC1jP4eXryhK5AZF7TXHUwMDEytpDmXGZ+3lx0wzm6dHIkt1FcdTAwMWRSboiGXHUwMDEzXVx1MDAwN7pcdTAwMDXMZuiPIVx1MDAwZm5SMVx1MDAwZft5KZj4cENcdTAwMDKyKVxyjvHz00xcdTAwMDKyk6CJ+VuMJt5GOIAvT1x1MDAwMTqrh3bHLM2G9lLH7qwuXHUwMDFjPzzub3xyXG5AdowgM1opXHUwMDFluVx1MDAxNfTb4rn5npJBt2+SXHUwMDEyJFxcuYOMQHlCXHUwMDA0Jqd/KMHLP4pkuyB8U/z5XFzXSOLFwuVcdTAwMTLOlOhyQ3taZoMwXHUwMDExQ0/FXVx1MDAwNfFcdTAwMTehRFx1MDAxYyRJOqLrJcJCxTcv4ZuJ3T1cdTAwMDJKyd3Y6ILBlopdXGY4Z2zcc1x1MDAxM49cbkFxZMVIodjgJnuQK3VcXDzSZazQ3CDacJo5fWlxLIQrz6xXTlx1MDAwMy3HtCu2XHUwMDFjkqphg9hZMqRcdTAwMDOWiHPlu0es43Rh4NaxRDR4XHUwMDEyXplcdTAwMDW9J8ubPkBcdTAwMGaYR97HXHUwMDE2jEeGoPjA5IamhnYuzVpcdTAwMTRgNFwiKEcnXCJcdTAwMTLm7i03fOAsN5aU8KBcdTAwMTSul1x1MDAxYmFJuFCKl9PcmM1cdTAwMDZugkrXgzb2MFx1MDAwNlx1MDAxY1x1MDAxNSVcdTAwMWWuXHUwMDAzYVxmW42c/1x1MDAxZjA+U2Fo19xsJmL1liPriuvXeFx1MDAxNIAkXHUwMDFjLlx1MDAxNt385YaOYo663Fx1MDAxNFO4nG5ohC2kpmRqM2Hth8jgqbm13a2N5eVcdTAwMTW52XrY2KlcdTAwMWbOL6yuTD+JY0lcdTAwMDHSMCQqXHUwMDA0JvGOXHUwMDA070ji6NRrnmhPtlx0XHUwMDE3XHUwMDFk6ZTeRlZcbk5I0Jb4T0AyoJN5enRcclxmyX9I3Ms/ioTdXGLNVaOe7qfiMd0xWFx1MDAwNbrf3iNBUOD2lyQnRcuRSUCPx5KJjlxchOtN3Fx1MDAxMy+QjGdr6ekhXHUwMDE35lx1MDAxNsKMXHUwMDBlXCJcdTAwMTiQpFmxV1x1MDAxY+fj2S2kKME6olXGXHUwMDFigodic5TjP1x1MDAwZYO0updQaeLLgWB3ZW/eqlx1MDAwNiz2y4BnT1xmoarlXHUwMDAxV1x1MDAxMINcdTAwMTjthZZEv5CrdlxyXHUwMDExl8JcdTAwMDdBd44n6Vx1MDAwNuWC51x1MDAwMNQ/XHUwMDA29s1cdNFcdTAwMTJML1+5XHUwMDE4UK1cdTAwMTXPXHUwMDE5XHQ+XHUwMDE4kph4RIS4XHUwMDE5XHUwMDA0Yoch8Ff64nRcbkJnrvi3xGyIkUA808NwJzTLXHUwMDEzsjnkQGyz8MYxOlx1MDAwM+tdXHUwMDAzxipcdTAwMTlcdTAwMWZra5wgnCd1pFx1MDAwMlx1MDAxN5Xb4pgoXHUwMDE3hVvgtlx1MDAwNOhIqmIhTON7vjp6gcg3ymJfnUNCeqXpm1x0NHj84lx1MDAwMM/sJZ5cdTAwMDMn5dO6ofhSc5cjM8I5XHUwMDEyPm7WTsysmFx1MDAxNVx1MDAxMnMhUk+CSKJF31x1MDAxZXtcdTAwMGWD6rFMvCZzseG3lqnA33m5j2UhtUajft1JbclqQmYzRVJcdTAwMTFkelx1MDAxMZVPJyFD5Nxs3Le2j1dWlnc7+2vdXHUwMDFmW78276+iqFxcnoRcZvYszPrU2zlcYj1j4Vx1MDAxZCt4w4XQIV5Jr9hpSFxum13WipQzvKmZYi5cdTAwMDVcdTAwMTlcYlx1MDAxNMtcdTAwMTQ/UvZbXuu5VGA1+I5cdTAwMTk3I5V9jZOZ5FxuRM6Q8eyses1cdTAwMGZcXFx1MDAxM0dIXHKu4lx1MDAxML0l5NGm/bUnVzef5MOvo1x1MDAxZvVcdTAwMTbedjPE4aTd6nRmzyvdk/NpYOZKXHUwMDEy/dJsXHJcdTAwMDdg30u82Y5cIlx1MDAxMkBcdTAwMTYz8Vx1MDAwZclV3Tpvykdxq+JcXLFcdTAwMDCiJkDEw1lOIMaQUuZcYsCMwljJYE60I9Ga0Fx1MDAxMlFcIuP+k1xyXHUwMDFiP7uHnbvD1ctcdTAwMWS/+v2qvbp7XFx5MkvDVDlcdTAwMDLdjFx1MDAxMKnhXHUwMDFkvcpxsCavREudx6vF5Vx1MDAxZDl/en5Vb/46v7hpwd63yFVG++UobtjE3lx1MDAxY+SGXHUwMDA10ic7UGgrmJlcdTAwMDZiMYpHZMZcdTAwMWHv1Fx1MDAxZuLAmnhcdTAwMWWfqVxikeeBc/qV4vbbiuyKXHUwMDE4ddaSQ1iBOHpvMpYuNjmypKf34qDcJGlMrnLNbFx1MDAwNJE90EE7uqpYXHUwMDFm04hmXHLlNWu6bLyvZlx1MDAxZLVcdTAwMTlcdTAwMDTRR1x0PN3SWTIvzYBmNdJcdOS262RZOvozp1x1MDAxYsRcdTAwMWI1a4nBXHUwMDBlyX7OpEc1V1x1MDAwM4+hYHzUWsRntTZS8fZItYgrte5Mp9a+q5/U/tWccGOIfMIwWJOYv7PJN4iQIbM7JcemufmUTS1N3Cwv6fer68f+sTp/eXT2dHa7tNA5O0b9KTiUJinnhI/gyMJFlH4wRM01L4iOY0CBrPq3XHIxzGxcdTAwMTPBXHUwMDEzmVxyx5pcdTAwMTCQ1I5KXHUwMDFk9+B4pJtDXHUwMDBlRPWaXHUwMDAyJVxmXHUwMDBiglx1MDAwZtqk1J+rufPchVnwP9ziweP5nFq5+imrt/ZiSFxuxcxxXGZcdTAwMTQqiygtLZ517s9D56l9stD52nrYX5RbJ+lESSF3SjeaJ1lbhSk9sYaiRaV4nJSHP1s13bla+17dXG72cWt9tbaUtr1Z2p/jZiesnlx1MDAxZI8uVS65QVx1MDAxMNaClaCdQS7CXHUwMDBmQ+34M1x1MDAxMblsueOfpMSV5F5557qPSdk9oKVcdTAwMDNcdTAwMDHSQy/7XHUwMDBmVbxxjVx1MDAwMlwi2tZJxVx1MDAxNUbATvekOVx1MDAwNi7ewSCpTYbqXGI9imr7nFx1MDAxZKH15lx1MDAxMFx1MDAxZKG5XHUwMDAy0kojfaJcdTAwMTXwl7xcdTAwMTZcdTAwMWY8sM1zanFcdTAwMDR1x9NcdTAwMTT6XHKK8HW2c7fVrs1cdTAwMWNcdTAwMTOBaT/OXFzVupGGxVx1MDAxZtdcdTAwMTa6gF4k5kRnX8O46Fa1XrlqNatphMvkPHknWaJBp1pWW+X5Vn6LoI+WvVxmm4qgRHjJXHUwMDA2LvewxFxiLeVcdTAwMDWCXHUwMDBmwlvnLef7XHUwMDA0XGZva4d6elo7XHQpXHUwMDAzcUhCelx1MDAxNVTsTecp9GmtoXPe8zqjVodgeVxuWKq+6aPlwvrs7sLy4ubB+rftysHFzfJ9ffP7+3lwR+RjsPM0d2h3XHUwMDE2Tlx1MDAxNlx1MDAxNte3Ol9cdTAwMTcvly52yk60yu+aXHUwMDE3+/73mpSVu26+alx1MDAxOX3dfCMxd91Cvst1ibZcdTAwMWbnntRkL+OyXURcdTAwMDZ7qf3pzvft8oos/aylK7LpaVPFaVfCsmpcYoHT+fRASoxSyDEgblJcdTAwMTY4rDxcdTAwMTFVpriXvqNcdTAwMWb0UilcdTAwMWZcdGpHWFx1MDAxZVxintTi8PefXHRNZlx1MDAwMlx1MDAxOVx1MDAwM1qq91Nkoze3XCKuXHUwMDBib3YoWSGdXHScgdD708felONfYk5ROZuUS6lcdTAwMDDP01xiTmwz70FrXCJ9XGZcdTAwMTKhaU3GiLHp2mCnvDaobsD3XHUwMDA3bFx1MDAxZa6r2cO1udZDWD1xlemnNSCktZx/7sDowSCcVNyFlOMhxFx1MDAxN6zLXHUwMDE5zf3xvMZLzuRC/7+S1qzf7y6sPy3NX56vPHX29q5vv0msTSHsWp1ccrveKWtdSJ0to3fLXHUwMDBiWvq9mH7Y5cpCy3hcdTAwMTdI5Sgz4KtVXHUwMDE2eFxuXHUwMDA2j9DiqLhcdFx1MDAxM1x1MDAxMbWx4C4nynpcdTAwMTWzXHUwMDA0/1x1MDAwMO9cdTAwMDdcdTAwMDBvXHUwMDAx4kxcdTAwMDfwZk+aMpyOjVx1MDAxNlLjN3vl9UG+f3tqgVdcdEN4ZrkhrFFuIClMcn6r5Vx1MDAwNjxcdTAwMDRpzk9GXHUwMDE5jMmfYIG7lGNhs4FPXHS8SytVf7Fyc/n12+lis3V1uXa9vtb5aPu89rX+dW1j+Wyjtbq48+taXHUwMDFlz35bbYxh3UNX19tnOyernlxm/kd1X1/zUC23bjFcdTAwMDHh0JLDqIqZXGJcdTAwMDExmUzfam886tSJXHUwMDAy+vtcdTAwMTD6JvVIfFx1MDAwMv5hhDY+eNDA+ThcdTAwMDP0w2syXHUwMDA0XHUwMDEwkVSP84jZoeJJ01x1MDAwZvTCOVxy4H//mSxl5lx1MDAwYkB8T4UzMv1AXHUwMDAzJlx1MDAwMnBcdTAwMWZDP/7VvG5VO1x1MDAxM1wiIVx1MDAwNeibQUJcdTAwMDa39FYqUi+RXHUwMDEymM1XevJcdTAwMDFcdTAwMWVcdTAwMDTdYcVjzZBraOJcdTAwMDJiXHUwMDAy0XduvcWMMlJNXHUwMDFimZZcdTAwMTFcdTAwMDQ9cO6x7LxcdTAwMGUpydVGesH9R1x1MDAxMbh/nfY4TFx1MDAxOLOM2Fx1MDAxZOtTfXw8NdRn1DDmj/QoZlx1MDAxOdR/VVx1MDAxMYpcZl7vk2WR9KKHXHUwMDFjXHUwMDFi1Ujg1mKRhlx1MDAxN6WjmyMyXGas6OWNXHUwMDA3qaBxOm9D527r+PFcdTAwMTLfwVOfz1x1MDAwNNYvN5YuLrauXHUwMDFi24+11uVa6/zse2dcZuvudVdVqG1u7rYu72+qJ+4wrLXaY1j3aPt8/Xb3fOl8caXV3jrefepu3S2PibmA4lwi8GFcdTAwMDLTOSoq/WknVFQyr4JcdTAwMTSQXHUwMDExPJtXacmtXHUwMDE5zIDF4KxcdTAwMTHeoLNcdTAwMWOh15GOLa/YXHUwMDFi8tMvxzVbO478n1RcdTAwMDVccpVIoXs9JXyi+qmna7Lj6Vx1MDAwMXhcdTAwMTSIhLGP11x1MDAwNulcdTAwMDDdSKM0XpnD49UxPaynWntcdTAwMTCpPy6Rolx1MDAwMN1cdTAwMTNMI/NcdTAwMTLGQzY2Tlx1MDAxN+92XHUwMDFlXHUwMDFiV5ur882uWulur2xdqqQkt2sn3WfRiomzNkZcdTAwMGIgXHUwMDFhblx1MDAxNFx1MDAwNFx1MDAwNFx1MDAxMzFbnvl4UEJKXHUwMDAyMO5+Yl3E1fYqz9JIwTOJXHUwMDE1XHUwMDA38qxMkW76tJDcy0BcdTAwMTEpMVx1MDAxMFx0iY5H2HPTpj4qVXZUkT8oyzpeepEkWUevPytYlZZSpSAzk1x1MDAxOY3neU9jz6hcIntXRSqjJ2Vyeyszr4ynWHuTOkNZXHUwMDFmlje567DekXtfr55cdTAwMWU3vv+wR6erS62v1YxzN0VD/IzhhrWWiD6JctRu+y3iQZDsm8BcdTAwMDWJXHUwMDFl8irc3tpATDshXHUwMDE1XHUwMDE3baIz3Fx1MDAwYiSpKrziJv/A7dRJnWiVXHUwMDFj5GdcdTAwMWRwK0vzgXVcdTAwMTnac+boMEGsNNiyTnB5qyQjz/lcdTAwMDD9YrDCkVG19ilZr2TBztC+KseVTi3Lqm73bms21HVb11k4XHUwMDE3u5rEjKjcLYzLoZ9T5K10dpU3krIxZOSmdlx1MDAwYvxZXtrzM8I/mlJmybpcdTAwMDNu5c5cdTAwMDEnzXJcdTAwMTZPXHUwMDEwJIPUisCN5FhcdTAwMWZcdTAwMTj5Vof+SThJca/ptNpVjUDPm6SezFx1MDAxOGmNSlReoDaKO2d9rlx06XtPy3PHV2d7P/QjVjZl9fD7/n5ps3lSjvk3mLe//5ZnhnLt+sTRnMdpZFx0OFx1MDAxYjp0glwiw9KjXHUwMDEyflRewtNcdTAwMWbe+/LIXHUwMDExhzxabijF+e/SXHUwMDA2I9WAXHUwMDE1TuIleFaOJkPc+Og43DGKOVny3F0wXHUwMDA0RCO5XHUwMDFhJq2RQ6KuUvHIUcCxyPnohZVgXCIzxiY/5LHV6Z61a3s76/9q/p9eTn291vm/XHUwMDEz8oRcdTAwMTfAVlx1MDAwMspcdTAwMGL29lx1MDAxZWCusvPitLXOWJSp0bJKeVH/sX9w87Bccmc3j425n81688rsX0w7mHN4iZuFXHUwMDFha5DdO4NllVpcdERu61x1MDAxOVxcdD7CWGPzPCOEXHUwMDFiW2lSM0pDWjwh5z0vMm9cdTAwMWP3l/Xqc1x1MDAxNVVcdTAwMWVcdTAwMWVcdTAwMWbPrzvffmyeV8+uto5v7y5cdTAwMTftR1x1MDAwN8c/gYu5XHUwMDEw21x1MDAxNepseSdLyEbBP1wi78fl5T392X1cdTAwMDZoXHUwMDA3hUbY4HrzXHUwMDFmg1x1MDAxZuzTRFIkuE0gN1xytdFcdTAwMDZCU1x1MDAwMO3cxlx1MDAxN0yw6Vx1MDAxMfH3sc2DXCJcdTAwMWJCXHJxhN9cdTAwMDbtXHUwMDBijfrJ5WrrtlMj+PzdmWBi0F5cdTAwMDBig9BetLf3gHaATFx1MDAxYVx1MDAwZii5+1x1MDAxNKQm4p6UXHUwMDE39WZl99fj/ndcdTAwMGJcdTAwMTenT1x1MDAwN1x1MDAwN23/dFY3XHUwMDBiU1x1MDAwZe3aa8+Jd4ZE3Fx1MDAwNitcdTAwMDfc7sY5XHUwMDAyfu7b/Vxcn/ym8YeZXHUwMDFkXHUwMDEzXHUwMDA2gVx1MDAxYtNcdTAwMTLvvFx1MDAxNdzu23InNovJec7ATUONhU/WcspcdTAwMWX/vJ537a8r3yr3y99cdTAwMTdkx1RcdTAwMWLvkJ+Wv+7o0e5iaO+1n5x44j03t8qSdyOlXHUwMDBmwUAqla+Wl/f0Z/dcdTAwMTmgXftcdTAwMDBcdTAwMDJVkKCNQSnNgCveySC4aZT13Fx1MDAxZFx1MDAxMNRbOX2Ge856XHUwMDAxgavuMDiiXHUwMDExKVKfxHbaXHUwMDFhci/fj3S703aDfavbvTy078HsSevqutKtXHUwMDFmN1xiQVvHXHUwMDE3tZPuTIdcdTAwMGLjJ4TvXHUwMDA1SJZcYi2X2eB4osz51kxWXHUwMDA3pd6ZV1xueFx1MDAxYajkMVx1MDAxNDwvccCI7bWyXHUwMDBlXG4lXHUwMDBmXHUwMDFkUJBMXHUwMDE4XHTeXHUwMDBijiBcdTAwMDJansOdllx1MDAxZK41XGJcdTAwMTW0s0Zyo10jh4kw/41cdTAwMWFz1L6kXG7kMFx1MDAxOW3soadbnZZkokym6vdo6bm4kXJMRkT4y7vbSq2Ffm/j9ujbIz52NuuNypBcdTAwMWSRrHUjWVx1MDAxMmPtr2NtXHUwMDEwPFxygyxj6aIpXHUwMDE4/DPba60lPdlq0vE0mcJGiZnixD/0eEVQipCBsMggafz+colcdTAwMWJWsknReDtDXHUwMDE55bxh1zZZx8FFp7X87rzEY/uclZKN13h/93F1isq3wlwi2+VOUTx1VnNcdTAwMWJcIlx1MDAxYlxiPmVyv05YXHUwMDAz2mKwxnL23HBcdTAwMWQ/39RcdTAwMDaq1jhu3ZdKXHUwMDE3TFx1MDAxN6aE+k9pw8Tpgjy5XG6t43lBgz5MXHUwMDFllWc8XHUwMDFhxy3oIZJcdTAwMWH4aqNYV0RW/rRhytD2Jl3dp2dcdTAwMGZyPif33E9R7DpTr4NcdTAwMGWKO1iMkqdcXNSFaVTlXHUwMDFi78L02+0xNW2YXG6IVHpcdTAwMWKm9ItcdTAwMThcdTAwMGazyzdmc5lcdTAwMWQpWSGxNySUXHUwMDBi81x1MDAwNoxcdTAwMTku2SM9bJ6d/1x1MDAxOJlcIvM6i0bz9GLreaJEwL6qjoZcdTAwMTa4XHTb81xmYTDcSfaPqKeJ+tnbiZ3kzlx1MDAwYtwkOY3ZQaa/XpGdalBcdTAwMWL/jtTuZHft8PDyYW++u+FuV5Z+/fL7m+tDUjsjR7Mkx0rt2G5cdTAwMDFHd525lomWu/Ve5VJcdTAwMWaSIDRcdTAwMDE8iUfhhJYseeKfpCRNXHUwMDE5s5OBWCkow53RiShFb8VvpkTKJvpcdTAwMTNcdTAwMWRVMi5ql2+Ax6mdscikzmhcdTAwMDeh1+AysWF6XHUwMDFhREJJS6J2klx1MDAwNzR+XHUwMDE4tYvoN/ravdpZKlxi975xrbN3XTupV1x1MDAxYSnfOPhaXHUwMDBlrKTLaFx1MDAxOcYoge8tXHUwMDExfTJQJI/ZicOKZVx1MDAxN1x1MDAxYZHqXHUwMDEwrFx1MDAwNS8xmZFcdTAwMGVp6Wd/SGI6cpxcdTAwMGbBXHUwMDExiX4jt99JM/4hM/naXHUwMDAzz1x1MDAwMtfR5OuxccRRtXhap85/JvqKf1x1MDAxY0ssIGV5zTqTlzEmnphcdTAwMWKcyOOJylx1MDAwNe5cdTAwMDGMqDnJnFx1MDAxNGFcXKDJ6iDlzyPPguMxsUlcdTAwMWKQuIlcdTAwMTU8eY6MfuaSOq2zN1j2ktBZMz3lXHUwMDExyWIoUWRSPGAg4U3/pPJ+8WamXHUwMDE4PM8ys2lKICdn03NlXHUwMDFhV1x1MDAxObxcdTAwMWZNfDjCu9vaUsW2zKVu+cre3vniynA0kUvdR0pcdTAwMTNcdTAwMWOvXHUwMDA3UFuhXGZcdTAwMGZcdTAwMGZcdTAwMDVcYlx1MDAwMUzcZSc1j5FcdTAwMDXtrVx1MDAwM+RcdTAwMTF8Rctli1x1MDAxM//MXHUwMDAyXGLtvFx1MDAwNIfIU0wwMlJxckRxiCk6PCbVcEdvg4Gr5Vx1MDAxM7SLWbCxPLrDXHUwMDEy+5qEXHUwMDA3cFx1MDAxOJpIXHUwMDBmRSOLXGbbVloldquU8JJHTspcdTAwMDDakC31cSwxR/uny1JcdDqnyLDhJFx1MDAwM++U12zqXGbQuaBcdTAwMTVPpeNcdJWaXHUwMDBlo0s2NHCeXHUwMDBlJJ9VrSVcdTAwMWRLleImXHUwMDE4itz9jZT95Vx1MDAxMOTO0Vx1MDAwMURcZsl0XHUwMDFkZj/Z00+C1VJZq0fR61x1MDAwNezOQLR+fFx1MDAwNHa32LpvNlqV6sxcdTAwMTXH/2vVXHUwMDE3P1rnny95zlPB9fKJ1SDXXHUwMDFi5qLGw/zyq0lymZ/3TnCfflx0hFBkq1xydPvxXHUwMDE2RdBAfI34hNIyact5bkBcdTAwMDaO9Di7XHUwMDEwXHUwMDEx0lxui0BcdTAwMGKO9JA5zr1cdTAwMDJDpOTpjzKIKIPGm5lcdTAwMWYxhtDT5CkqQiWrjfsuQt9r7Yrv2M3kuFK53Wss3zdcdTAwMWaaXHUwMDA3ZnVu92H3YHlnSO6nQz9cXPdxg8O1XHUwMDE3Xlx1MDAwNWm4UziJSoh+2lx1MDAxOaG4rJfwk7SlNcVcdTAwMWXCLHHin1mSXHUwMDFm+i5liDlcdTAwMTFUS6PfxUc4XHUwMDA09SOgIfqrkTtcdTAwMTd5XHUwMDFk6STSZ1Mo0Fx1MDAxYfqfXHUwMDA2kNbIMFx1MDAxY5tcdTAwMWH7pCDGMKTNaE9cXDo2+7lP/8BbXHUwMDA19Fx1MDAxMNk5q8FcdTAwMGW14Xeif+niVIL+aWmc0Fx1MDAxOHhcbnwv13cg/otSXG5S3OCVY1x1MDAxYVx1MDAxMek/+erNU0549qN6z3OqSZf84X+/N1Wo8q/K8z8yXHUwMDFm6Vx1MDAwMWlIXHUwMDFkw5Np1Ssy65FMZDv+5jFcdTAwMWF8wJH071x1MDAwYv1bpjsxbVN4XG641CDZy76E8VC7/GKifKeeXHUwMDAyQZa4XHUwMDA2Plx1MDAwMTxcdTAwMDdtQLCDXHUwMDEyISjnNLdk9Um5JjSzXHUwMDAy+DFcdTAwMDNcdTAwMTjl0rpCXHUwMDE5J0VAJ1Gb4E2I6I4/Ulx1MDAxZZHy5lx1MDAxOLL6OGvSqFTjT6vM4C8xdu14kvE7MrvTJbnnrZy73/qxd3a4ML/nXHUwMDE2cMi8PoNKXHUwMDBmM3h9MsxOycBDXHUwMDBmgkfgzlx1MDAwNyHuhiPgXHUwMDE0xOhcdTAwMWOpVu299b6Q22Vcblx1MDAxNP/MastcdTAwMTUliugk0T9uhTNl1C7wQZKkTCx4I6NZif3or5baeoncv1x1MDAxZidcdTAwMTD8XHUwMDFkJq+PuVx1MDAxY9Fxz4lrVrskXHUwMDEx1ciRfbqgwC05rDdD7fedaF26LJWhdUTAXHUwMDA1p/Sy/4fYuIvTOk54XHUwMDE0SNet6KRxtnDSsHeR3pZ/eFxcgYZvXHLhxyMrXCKQesM0VW6yiZzkhrPsn1x1MDAxZDuR48k25m1dXHUwMDAwaVx1MDAxZifdV0fXs+eLZHnm353eK632f6aB21x1MDAxNZCpRNB2mKtcdTAwMWGa7v31W6F/qVxcX+916Ym8Kr4vd/Xa/XyqsPBcdTAwMGZDaU9bfOltiz/2n7/+8/9cdTAwMDFUVeT6In0=Server #1Container AContainer BContainer CPerforatorAgentCollect profileServer #2Container DContainer EPerforatorAgentCollect profilePush profilePush profileGet serviceprofileStore binary metaStorageStorageStoragepodsSymbolizerpodsPerforator databasesPostgreSQL(binaries)ClickHouse(profiles)S3-compatibleobject storeStore profile metaStore binary/profileDownload matched profiles/binariesFind binary metaSelect profiles matching {selector}

Components overview

Agent

The Perforator agent is the core of our profiling infrastructure. The agent runs on each node inside the cluster, collects profiles using eBPF, aggregates, compresses and sends them to the storage via gRPC in the pprof-compatible format.

Agent connects to kubelet to identify running pods on a node. Also agent tracks all the processes on a node and analyzes running executables. To profile, the agent uses perf_events Linux API to trigger eBPF program on each perf event like "1M CPU cycles" or "1K major pagefaults". The eBPF program collects info about thread it was invoked on like thread / process id, thread / process name, userspace & kernelspace call stack and so on. The program sends collected samples to the user-space part of the agent via eBPF perfbuf API.

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nOVcXFtT20hcdTAwMTN9z6+g+F7XszM9933jflx0XHUwMDEwMFx1MDAxMCC7Wylhy9ixkVx1MDAxY1lcXLf2v389hiBZXHUwMDE3I8A2uFakXHUwMDEyXCKNNKNRnz6ne1r659PCwmJ81/dcdTAwMTf/WFj0b1x1MDAxYl6v04y8m8Xf3P5rP1x1MDAxYXTCXHUwMDAwXHUwMDBmwfD/g/AqalxmW7bjuD/44/ffkzNII7x8OMvv+Zd+XHUwMDEwXHUwMDBmsN2f+P+FhX+Gf6f6ifxG7Fx1MDAwNVx1MDAxNz1/eMLwUKorTrN798Jg2C2jVlpGXHUwMDA1U08tOkHTv3XXPOcrydU6g1VcdTAwMWNF7DfxSMvrXHL85IjbtVx1MDAxOH7Z+bHp+Yfr+j7q7vhcdTAwMTeNPXl/mZze6vR6h/Fd7+FWvUb7KkpccnVcdTAwMTBHYdc/6TTj9q+ZSe1/Om9cdTAwMTDixCRnReHVRTvwXHUwMDA3g5Fzwr7X6MR3w3tLbvthbv5YSPa4W2ScamKNpKCpXHUwMDE1YE1yXHUwMDE5d1x1MDAwMWUpoUxyy4SWQmSGtVx1MDAxMvbCyFxy63/Mdz/JwM69RvdcdTAwMDJHXHUwMDE3NJM2rZbfsDZpc/N4s9qYp31tv3PRjnEnXHUwMDE3NunMXHUwMDFmzjnjQK1cdTAwMDaTelCui/5Wc2hcdTAwMTV/JzNcdTAwMWR5l/6WOyW46vXSk1x1MDAxNTRcdTAwMWYn65f1JPbDXHUwMDFm9/yb3INrv5ayu6SHq37TezBcdTAwMDSmuWFaaoNDk0/He52gm+2+XHUwMDE3NrqJ7XxK9ZUz5di/jYusmHFTasVcdTAwMWGUNVZKKLLi1epWXGbt3ln78/3KTZM34/O98Me56e2UWHHGXHUwMDFh38+GgY61YTMpXHUwMDFijiMvXHUwMDE49L1cYi1cIm/HwFxy4biBXHUwMDAxoammPG/VQlx1MDAxMKZoalx1MDAxM1kjXHUwMDA3ramSOjXMV9v4yIGpXHUwMDFhczKqMIhcdTAwMGY790M8KWJo8a26VuveZafnnk4yS0Orx0n+7EeB38NpbqRcdTAwMWWGO7jU61xcOFx1MDAxOCz2/NYoPuJcdTAwMGUyxtPhOOwnR1x1MDAxYtiZ11x0/Cg/WWHUuehcdTAwMDRe72hcXMfeVVx1MDAxY9b9wcNNxdGVn55cdTAwMTd/89eTZVx1MDAwNMZCeiw7SSqze3/hmlx1MDAwYmHRokxi8SlYr1WH9fXP7ct6sF/bvvnWU0HH37nY7fbmgJzkXHUwMDE4YDPOXHUwMDE5sUJohza8mlGZkb2Mn/zz1rnv53EtXHJcdTAwMTCJqFx1MDAwNKpcdTAwMTGXnLFcIrZSbpzWKKFccjPUJM/zibyMXHUwMDE2eLpIPPh/jLzQM5ZcdTAwMTm5YYKDlrxQga1XN/LW4fZ1KNeOumZ7c39X22/b3c+tj85dTIw3cTM5XHUwMDEzXHUwMDFmS1/MyrxhP09YTOLTXHUwMDEzgjF4u2HPK2NcdTAwMWRcdTAwMGbQnmfPV1x1MDAwNd3Ogq2EXHUwMDEx2b1PQFZcXKNEV0mDXHUwMDE0kDeqXHUwMDAzuau+N7aO1ronuz9XgyNf7Vx1MDAxY2yv1EuA3IjCwaDW9uJG+1x1MDAwM8BZUE5cdTAwMThcdTAwMDW0SWBWZdEs0Ma4MZopxbjmTGZcdTAwMDb2MsI6h1x1MDAxNpyf55GMXHUwMDEylGhtpOZKM2lcdTAwMGJ0KDOMUIugXHUwMDExSoLmObZcdTAwMTLGcsmUfa9I6+mc5OwyhklZjVx1MDAxNFx1MDAxYsvHn8XGXHS7bq39XGLvd+Bwny4+tfv3t+LLPpxs/Kugdqv11z26eb/7RUWrOtpcdTAwMWHt5Vf/Xlx1MDAxNIU3Va8rjo+BmbONL1v33Vxys3p1s7l5PZjAdTV0v8mNuzV5uFx1MDAxMt7VY14/OG/Iatd9/O3dXHUwMDE1gVx1MDAwMF3mSFx1MDAxMEdcdTAwMTJcdTAwMWSwKU7KbFb3JMU2MTPdm2jFl3lcdTAwMTGNwlx1MDAxNlx1MDAxOFx1MDAxM1x1MDAxONBLlJTJPD24XHUwMDExo4miglOKXG5cdTAwMTij/jd5kbK0XGbqXHUwMDAxgo9BQYEs0IYopSxoYFxugEI+jKVcdTAwMTKHZpR+d1WgXmDFharA+VJtkNlcdTAwMDSllmk90miMKNj3o1ZcdTAwMTh5cVx1MDAxOP1cdTAwMTV4XHUwMDE3I5JrRFx1MDAxYzTwkFx1MDAxZo2RXHUwMDA3l51mM83Eo1xu4TmuzIqGMcOahXjgulx1MDAxY/NUMK5UOkWTwvxWdcxvrG/a+NA7uV2r7ar6UWdpnTKYXHUwMDBi9YCaYEwwoFx1MDAxNUwwXHUwMDE527CNXHUwMDAy1Fx1MDAwYqVcdFfJT9JLXCJcdTAwMWVkPjXLqFx1MDAxNNxcdTAwMDBMIG01Q8FcdTAwMTDfn6nV02/N7yvrJ+trXHUwMDExKLV7XHUwMDFivbdgOD0xe1x1MDAwN1tcdTAwMTer33rN79dM7Vx1MDAxZVx1MDAxY6qtlVx0XFyXX1x1MDAxZtuz6/PtlS/Rqr+5e7p+x0MzX4JBKpbd++Q8XGZH3yx0cVx1MDAwZWG7uvMotomZOo/Xilx1MDAwNs5cdNfCSE6RrlhcbrruXHUwMDAyhjGijHbZaS5cXJZ6Ku6DXHUwMDBiQ6Th1lxirlx1MDAwYnSDtEThQ8RcdTAwMDBcdTAwMTF9XHUwMDA1w1x1MDAxMCPnSKjGcFx1MDAwNJI7m1PVICzRXGbnXHUwMDE5J1xcol1aqJxL2OlcdTAwMDRXt1x1MDAwYt1hKnpKiuFcdTAwMTl+zCqG4lx1MDAxMc1CLCBcdTAwMWaW4Z1LTVx1MDAwMUrg/rk63PdbvbOj+krQ3/m58+1GXHUwMDFm26Xayv1cXGhcdTAwMDXLxmlcdTAwMDUzQa3g++d+yyuIXHUwMDEwoEhcdTAwMWTQfO5bXHUwMDE5Q7k0cr7SXHTc/7pUX7H9xsbyTrB5oI6/3qrtXHUwMDE5sO3Y674hnfBRWJxB6UJcdTAwMDDnQoCgxatdO9VRXfzo5oHELZI4Rv9aSCNcdTAwMWOqR0GtXHUwMDE54U+g5vatgX8xh1x1MDAxYkkoIE1cdTAwMTdcdTAwMDX+Rlx1MDAxMew2tWWxjsSOdMfk/Mf9amTvXHUwMDE4xvaX99f/XG76UXgxJb5+hqOyfF00npmwNdWlRVbWMtBW8cLqlN3qwO5cdTAwMWRcdTAwMWTY/eWDev1uc+NzcFx1MDAxYdSCn1/CeaBr4JRcdTAwMTIppFQ4XHJuMS+jzrUkyI+AbG6EtPptyPZk07RaeWRcdTAwMGKhiED/oVA8YaRgU4ScLGVTTqRVLohQlGqZctaPXHUwMDEwt1xiMMPMJFJ7M2Tz472jr8taRmtcdTAwMDdn7Vx1MDAxZrXrXbF2fNKaQUz+YViXs/JcdTAwMTJI7N9KyUxh5m2vOjyLJ3lcdTAwMGV4XHUwMDE3hHLrdlx1MDAxY4RcdTAwMDXLqVJ8XHUwMDA0nlx1MDAxNnmPcYUqllx1MDAxYUHTWe1JXHUwMDEyL1x1MDAwM6R3t/DMqVx1MDAxY9pFQaWJ4Vx1MDAwNKU058jQzGVLIYtOpnGYysJcdTAwMDTqTN53OV5Zwqxi1EiJXHUwMDAxjmZ2pNFcdTAwMTg+Xtk/nlx1MDAxMlx1MDAxMT/DPllcIlx1MDAxZVx1MDAxOciEXHUwMDE4+MG9XHUwMDE04NuW15BcdTAwMTmhhMI5LET3l+roXHUwMDFln/GcXHUwMDFjupveoO1PeFneXG5Xw0U1XCJbK2ZH2ZdcdFBEW1BcYn1hMLB+XHUwMDFi/Zaty1x1MDAwM1x1MDAxYbRx0Y2L2I1FlZ/Ht7BcZilcdTAwMWGdkOXALbU0VfDzXHUwMDAwcMlQRqnpxNIwLfatb3R19FXex/21XHUwMDFkXHUwMDE5bzSu4/bF8nRZMvVcYr0oXkaT71x1MDAwNFx1MDAxN6N3/fhSQZV1tKHbaVxcuSmoUVwikCs1ZdxIXHUwMDFjWqp+wj1ccq/v0Og0XHUwMDE0XHUwMDA1LpXAXHUwMDE2qLlyXHUwMDEz61x1MDAwN83nxzQ+U5dcdTAwMWFcdTAwMTNcdTAwMGVJXHUwMDAzlVx1MDAwMs2bXHUwMDFiKlx1MDAxOIXckJggXFxcdTAwMWFKXHUwMDAxnPBDQOjcmHreIF5cdC8vOzFO/X7YXHTi7Fx1MDAxNFx1MDAwZudyyfmgtu/ljFx1MDAwYu8pfSzrrPruiqNG9GfKVGjabujT73//Vti6XHUwMDFjTG6r5XGUXFzwU/rfXHUwMDE3lzFCdueTm9XMSFZSxbhf3c1cdTAwMTZjZS7cLEokYlx1MDAxNFx1MDAxM1xujZ7TrJdlXFxcdTAwMTNj0MWijSqbLkyaqJeVnCj2yvRcdTAwMDVHesCBq7lfgKievjj046v+X4HLXHUwMDFhLLikXHUwMDAx3tmU5NMz+iErn8ZcdTAwMGVs2nJKlC81XHUwMDAy5Vxc2Fx1MDAxMSNJXHUwMDAx/aA60MdHlVx1MDAxZlx1MDAxOejAjWNcdTAwMTMmKTOu5DExtmEyQypiQFx1MDAxOae1XHUwMDA0lfC2aKlcZudcdTAwMTIkUVJLsCjnXGYv0FKaXHUwMDEyzlx1MDAxOeAwrESHw/Jo11x1MDAwMtmSTqcmf2paqq+jlaW7XHUwMDEzr1x1MDAxZZx4VFx1MDAwNeHX3a1TeJGWMlx1MDAxNNK1d5PXUuNcdTAwMDOlXHUwMDEx3YKESSVFtYRhK3K1UKlWj8LFXHUwMDEyikE5V8JVmUhl0tfp3I4qlSnrLNR+XG5cclx1MDAwNlxyXHUwMDFmeUQwVIF57cc04Vx1MDAwMu/KsuFKt3jZeOdJg9VcZlx1MDAxMI3PXHUwMDBlkNBBKi1V+vRaXHUwMDBlf89er1xm08ODSlx1MDAxMaFAXGJXcYguR5tcdCk6U/5SpXLezYAo9PT16p6+XHUwMDE4snPh6Vx1MDAxOeVcdTAwMDQwzuHKKlxynI0mxjR3Mls42asxXHUwMDEwmo6nx7BcdTAwMDXNjFwiJMG9VsletzDF3Vx1MDAxMJl617yYtTr1XvO0ld1cdTAwMTFcbqpcdTAwMGI/Wug42Vx1MDAxNl31Y1x1MDAxNFNeo72wt9C4a/T8wZRk3jOyJivzqo9y2pqvvNqEoeVbjsI8sZ6UIzh8wcL02LKAj+xcYphcdTAwMTGGKFx1MDAxN0uj6MNcdTAwMWbILE1j5GeZS9RKKmxcbmWTlXxcdTAwMDRVgNOdXG6jNCZcdTAwMGK+XHUwMDFiXHUwMDAwijBcdTAwMDPDKIorSW1BNYqQwJSe0sstXHUwMDE1VN97JrleXCJ0XHUwMDA0indjJFx1MDAxN4JZzpRNtXpcdTAwMTA6mlx1MDAwMFI1iiE3oYZJ8TrxNX55e3RM2JEwVFxibjVcdTAwMWGBKVx1MDAxMItALFx1MDAxMlx1MDAxNapcdTAwMTJcdTAwMWNcdTAwMTJCVuczb/OksEot3m15W3+hXCIq9YRSl5boMFRcdTAwMDRS2TTEU67wqLorXHUwMDFjX8n0oV2h1Zag2GFgqKJKZ8Jfd1x1MDAxNOGAglx1MDAxN9BXgn3bW+mloogxXCIlt+Cs3Vx1MDAxOUfRYoLgXHUwMDA05SuKXHUwMDBll/fF0Clp82sxXHUwMDAxpfRkXHUwMDE2XHUwMDBiZ1x1MDAxOFx1MDAwMFx1MDAxZq2tXHUwMDFl3W7WWtdw293Z2Nk++rl/f/SxXHUwMDE2XHUwMDEzXuLTkE9cdTAwMTlw0FxcXHUwMDBidKaGp1o9+TSlXHUwMDE0oHhcdTAwMDRcZqTwT35mKznayitcdTAwMWNcdTAwMTiVXHUwMDBmQU6FNK7QTFx1MDAxNaxwMI5qwL2lp6hBy8KJnWtHWyvHk9vySHqhqy1cdTAwMGI+oXzV1kiqcYZcdTAwMGJjz+PqfrZcdTAwMTgtc+FntUJcdTAwMTViXHUwMDAwbVxm6d5wPVrizJBcdTAwMGVcdMWQVFx1MDAxYoV0P608I0OatUK+MuxE5WStXHUwMDAz03uGnbNdUKj7/TDCKG7gXfZ7ZZ9EeGuQ+Yx6yFx1MDAwNpllY5pJXSRLSYCsmuJcdTAwMDKda9n3fb5WR7mNlrZpp2HXa/f8plx1MDAxN4X0dDlcXJ9cdTAwMDLKJ19cdTAwMThcdO7zXFzodLlcdTAwMTGObjJiypWNXHUwMDEyt2bt1rZBvvGLXHStRlx1MDAwM5p6WoWRqFx1MDAwNy3Sg57E60szrIxcXDptf/F/yFx1MDAxZmsrZ9/XRc2efO8u2//QZ1ximJCllZHGwVNcdFu4pn9SXHUwMDFknsVzPFN4vrIwkmtDUFxmMVe5XGZajGZ9XHUwMDE4N1x1MDAxNo9yKnGKXFw9xtuW9MtcbiPBSIzqSzn42ZJIt9wlXGbnc0/Cr66J3PPjmzDqTomMnyGfLFx1MDAxOedcdTAwMDYz7cSuYaVFOyBRYjNLXHUwMDBiayNPq1x1MDAwM3y8XHUwMDFm/NgqW3KCvFx1MDAwNspcbvfugcxU7UgmiORggSlcbjSdK3hccsSb9LxV9GqCXHUwMDA0hvGklVx1MDAxNLBD9CRcdTAwMDU4t4IoadBcdTAwMWZLQPPHgCCLc8RcdTAwMDRwOVx0lM8wmeEvtevfZWvb34uWT1x1MDAwZvun2q+dmo+VzHhJZSSgXHShv7WWu5dcXExBXHUwMDE5XCKqPWxcdTAwMDNUWs5cdTAwMDFcdTAwMWR3bmIr5TLGu5yFdC5cdTAwMDN9v0Zdyaw2zpjzqVxmXHUwMDAwl4NxXHUwMDE1XGKIXHUwMDE2bVFo5sY0T6lcZq5cXE7JXGKgXHUwMDAy406JtJk+nUvCcFx1MDAxMqxcdTAwMDKttTXKPHe5UmS6rSYtkUJQbsF9o9C8NFx1MDAwM136pYfS/LNER6SFKl6JO6vusItxN1x1MDAxN1x1MDAwZVx1MDAxYi2V4IM1WnNLU4rowV1cdTAwMDNcdTAwMDJMaMnQ5q2xb1xmmMrcNdpcdTAwMDMxJUWWgqNISW+5XHUwMDEydqBIJaNcdTAwMWarnlNBVj0rsnbrMlx1MDAxMK6QXHUwMDExTWtaWZFnVEhWiJWN6aV67NOj81j0+v3DXHUwMDE4p/nJcS9ed/yb5UKp7zbHc0PX4PDmXHUwMDBmmfffT//+XHUwMDFmVeVyXHUwMDAwIn0=KernelspaceUserspacePerforatoragentLinux kerneleBPFprogCPUSetupeBPF programTrigger interrupteach N cyclesReportsampleNetworkExport profile

Agent collects samples from the eBPF program in memory and periodically sends them to the storage over gRPC. By default, for each pod an agent will send a profile every minute. We call this profile, consisting of the samples of one workload over one minute, an atomic profile.

In order to generate human-readable profile, the agent should map addresses of executable instructions to source code lines. That process, called symbolization, is compute-intensive. If the same code is executed on thousands of nodes, the agent should run the same symbolization on each node, which is proven to be really expensive. So we took another approach.

In addition to profiles, agent uploads executable files found on the profiled nodes. This can sound scary, but with careful synchronization we guarantee that each binary file is uploaded only once. The binaries are uploaded through storage microservice to S3 and PostgreSQL storages, and can be post-processed later to generate symbolized profiles. Binary files are identified using build-id: unique identifier of the compiled binary, which is often computed as a hash of meaningful ELF sections. Some executables do not contain build-id, so we compute so-called pseudo build-id: hash based on a few random portions of executable text.

Note

While in theory we can support external artifact registries, this feature is not available now. Feel free to discuss and contribute.

Databases

Perforator uses three different storages. All the other microservices are stateless.

  • Raw atomic profiles, binaries, and some post-processed artifacts of binaries (GSYM data) are stored in the S3-compatible storage. S3 is cheap and scales well.
  • For each atomic profile we write a row to the ClickHouse cluster. This allows us to quickly find interesting profiles using complex selectors, because ClickHouse is blazing fast. See ClickHouse table structure for details.
  • For each executable file we write a row to the PostgreSQL cluster to synchronize uploads and track binary TTL. We have found that there is not too many executable files and they can be easily stored in an PostgreSQL. However, it is quite easy to use your custom SQL database instead (probably a few hundred lines of Golang). See the source code for details.

For more details about database structure see database reference.

Storage proxy

Storage is a simple gRPC server that proxies upload requests from agents to ClickHouse, PostgreSQL and S3. Storage proxy is stateless, despite the name, and can (and should!) safely be replicated. We run hundreds of storage pods in our largest cluster. Storage can optionally provide agent authorization using mTLS.

Symbolizer

Symbolizer (or proxy in the source code) is a main user-facing service. Symbolizer allows user to list profiles or services, build merged profiles that span multiple atomic profiles matching one selector and so on. Symbolizer consumes a noticeable amount of resources: symbolization is heavy. We are working to optimize this. Likely the symbolizer itself is often running in the same cluster we profile and can be easily self-profiled.

Symbolizer provides two variants of the same API: raw gRPC interface and HTTP RPC using beautiful grpc-gateway. The gRPC interface can be used by CLIs and automated services like profile quality monitors while HTTP API is used by our web interface.