blob: 163964b6aedb1c4f8fe55f9e0a029c82986ff477 [file] [log] [blame]
(window.webpackJsonp=window.webpackJsonp||[]).push([[57],{GlUp:function(e,n,a){"use strict";a.r(n),a.d(n,"_frontmatter",(function(){return i})),a.d(n,"default",(function(){return b}));var t=a("k1TG"),c=a("8o2o"),r=(a("q1tI"),a("7ljp")),s=a("hhGP"),i=(a("qKvR"),{});void 0!==i&&i&&i===Object(i)&&Object.isExtensible(i)&&!i.hasOwnProperty("__filemeta")&&Object.defineProperty(i,"__filemeta",{configurable:!0,value:{name:"_frontmatter",filename:"src/pages/docs/installation/caching.mdx"}});var o={_frontmatter:i},l=s.a;function b(e){var n=e.components,a=Object(c.a)(e,["components"]);return Object(r.b)(l,Object(t.a)({},o,a,{components:n,mdxType:"MDXLayout"}),Object(r.b)("h2",{id:"caching"},"Caching"),Object(r.b)("p",null,"Superset uses ",Object(r.b)("a",Object(t.a)({parentName:"p"},{href:"https://flask-caching.readthedocs.io/"}),"Flask-Caching")," for caching purpose. For security reasons,\nthere are two separate cache configs for Superset's own metadata (",Object(r.b)("inlineCode",{parentName:"p"},"CACHE_CONFIG"),") and charting data queried from\nconnected datasources (",Object(r.b)("inlineCode",{parentName:"p"},"DATA_CACHE_CONFIG"),"). However, Query results from SQL Lab are stored in another backend\ncalled ",Object(r.b)("inlineCode",{parentName:"p"},"RESULTS_BACKEND"),", See ",Object(r.b)("a",Object(t.a)({parentName:"p"},{href:"/docs/installation/async-queries-celery"}),"Async Queries via Celery")," for details."),Object(r.b)("p",null,"Configuring caching is as easy as providing ",Object(r.b)("inlineCode",{parentName:"p"},"CACHE_CONFIG")," and ",Object(r.b)("inlineCode",{parentName:"p"},"DATA_CACHE_CONFIG")," in your\n",Object(r.b)("inlineCode",{parentName:"p"},"superset_config.py")," that complies with ",Object(r.b)("a",Object(t.a)({parentName:"p"},{href:"https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching"}),"the Flask-Caching specifications"),"."),Object(r.b)("p",null,"Flask-Caching supports various caching backends, including Redis, Memcached, SimpleCache (in-memory), or the\nlocal filesystem."),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"Memcached: we recommend using ",Object(r.b)("a",Object(t.a)({parentName:"li"},{href:"https://pypi.org/project/pylibmc/"}),"pylibmc")," client library as\n",Object(r.b)("inlineCode",{parentName:"li"},"python-memcached")," does not handle storing binary data correctly."),Object(r.b)("li",{parentName:"ul"},"Redis: we recommend the ",Object(r.b)("a",Object(t.a)({parentName:"li"},{href:"https://pypi.python.org/pypi/redis"}),"redis")," Python package")),Object(r.b)("p",null,"Both of these libraries can be installed using pip."),Object(r.b)("p",null,"For chart data, Superset goes up a “timeout search path”, from a slice's configuration\nto the datasource’s, the database’s, then ultimately falls back to the global default\ndefined in ",Object(r.b)("inlineCode",{parentName:"p"},"DATA_CACHE_CONFIG"),"."),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{}),"DATA_CACHE_CONFIG = {\n 'CACHE_TYPE': 'redis',\n 'CACHE_DEFAULT_TIMEOUT': 60 * 60 * 24, # 1 day default (in secs)\n 'CACHE_KEY_PREFIX': 'superset_results',\n 'CACHE_REDIS_URL': 'redis://localhost:6379/0',\n}\n")),Object(r.b)("p",null,"Custom cache backends are also supported. See ",Object(r.b)("a",Object(t.a)({parentName:"p"},{href:"https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends"}),"here")," for specifics."),Object(r.b)("p",null,"Superset has a Celery task that will periodically warm up the cache based on different strategies.\nTo use it, add the following to the ",Object(r.b)("inlineCode",{parentName:"p"},"CELERYBEAT_SCHEDULE")," section in ",Object(r.b)("inlineCode",{parentName:"p"},"config.py"),":"),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{className:"language-python"}),"CELERYBEAT_SCHEDULE = {\n 'cache-warmup-hourly': {\n 'task': 'cache-warmup',\n 'schedule': crontab(minute=0, hour='*'), # hourly\n 'kwargs': {\n 'strategy_name': 'top_n_dashboards',\n 'top_n': 5,\n 'since': '7 days ago',\n },\n },\n}\n")),Object(r.b)("p",null,"This will cache all the charts in the top 5 most popular dashboards every hour. For other\nstrategies, check the ",Object(r.b)("inlineCode",{parentName:"p"},"superset/tasks/cache.py")," file."),Object(r.b)("h3",{id:"caching-thumbnails"},"Caching Thumbnails"),Object(r.b)("p",null,"This is an optional feature that can be turned on by activating it’s feature flag on config:"),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{}),'FEATURE_FLAGS = {\n "THUMBNAILS": True,\n "THUMBNAILS_SQLA_LISTENERS": True,\n}\n')),Object(r.b)("p",null,"For this feature you will need a cache system and celery workers. All thumbnails are store on cache\nand are processed asynchronously by the workers."),Object(r.b)("p",null,"An example config where images are stored on S3 could be:"),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{className:"language-python"}),'from flask import Flask\nfrom s3cache.s3cache import S3Cache\n\n...\n\nclass CeleryConfig(object):\n BROKER_URL = "redis://localhost:6379/0"\n CELERY_IMPORTS = ("superset.sql_lab", "superset.tasks", "superset.tasks.thumbnails")\n CELERY_RESULT_BACKEND = "redis://localhost:6379/0"\n CELERYD_PREFETCH_MULTIPLIER = 10\n CELERY_ACKS_LATE = True\n\n\nCELERY_CONFIG = CeleryConfig\n\ndef init_thumbnail_cache(app: Flask) -> S3Cache:\n return S3Cache("bucket_name", \'thumbs_cache/\')\n\n\nTHUMBNAIL_CACHE_CONFIG = init_thumbnail_cache\n# Async selenium thumbnail task will use the following user\nTHUMBNAIL_SELENIUM_USER = "Admin"\n')),Object(r.b)("p",null,"Using the above example cache keys for dashboards will be ",Object(r.b)("inlineCode",{parentName:"p"},"superset_thumb__dashboard__{ID}"),". You can\noverride the base URL for selenium using:"),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{}),'WEBDRIVER_BASEURL = "https://superset.company.com"\n')),Object(r.b)("p",null,"Additional selenium web drive configuration can be set using ",Object(r.b)("inlineCode",{parentName:"p"},"WEBDRIVER_CONFIGURATION"),". You can\nimplement a custom function to authenticate selenium. The default function uses the ",Object(r.b)("inlineCode",{parentName:"p"},"flask-login"),"\nsession cookie. Here's an example of a custom function signature:"),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{className:"language-python"}),'def auth_driver(driver: WebDriver, user: "User") -> WebDriver:\n pass\n')),Object(r.b)("p",null,"Then on configuration:"),Object(r.b)("pre",null,Object(r.b)("code",Object(t.a)({parentName:"pre"},{}),"WEBDRIVER_AUTH_FUNC = auth_driver\n")))}void 0!==b&&b&&b===Object(b)&&Object.isExtensible(b)&&!b.hasOwnProperty("__filemeta")&&Object.defineProperty(b,"__filemeta",{configurable:!0,value:{name:"MDXContent",filename:"src/pages/docs/installation/caching.mdx"}}),b.isMDXComponent=!0}}]);
//# sourceMappingURL=component---src-pages-docs-installation-caching-mdx-0d697988ad588b89277a.js.map