跳至正文
Wener Notes

CubeJS 配置

约 3 分钟阅读
标签:配置
  • 环境变量配置
    • CUBEJS_DEV_MODE=true - 开发模式
    • CUBEJS_APP - APP ID
    • CUBEJS_TELEMETRY=false
    • Environment Variables
    • 映射方式 CUBEJS_DB_TYPE -> dbType
  • cube.js 配置
  • dev mode
    • 无 auth
    • 单节点 cubestore
    • background refresh for in-memory cache, cheduled pre-aggregations
    • log level trace
    • playground localhost
    • memory as the default cache/queue engine
    • log incorrect/invalid configuration for for externalRefresh /waitForRenew instead of throwing errors
cube.js
module.exports = {
  telemetry: false,
  logger: (msg, params) => {
    console.log(`${msg}: ${JSON.stringify(params)}`);
  },
};

配置说明

上下文关系

  • 请求 - ExpressRequest
  • appId - RequestContext
  • COMPILE_CONTEXT - RequestContext
  • jwt - securityContext
  • SECURITY_CONTEXT - securityContext
    • 尽量使用 queryRewrite 而不是 SECURITY_CONTEXT
    • 用于 row level security
TypeScript
interface CubejsConfiguration {
  // Schema 文件路径 /schema
  schemaPath: string;
  // REST 接口路径 /cubejs-api
  basePath: string;
  // 默认 /
  webSocketsBasePath: string;
  // 自定义 logger
  // 例如 console.log(`${msg}: ${JSON.stringify(params)}`);
  logger: (msg: string, params: object) => any;

  // 数据库类型 - 每个 appId 请求一次
  dbType: string | ((context: RequestContext) => string);
  // 数据源配置 - 一个数据源请求一次
  driverFactory: (context: DriverContext) => BaseDriver | Promise<BaseDriver>;
  // 外部数据库类型 - 每个 appId 请求一次
  externalDbType: string | ((context: RequestContext) => string);
  // 外部 rollup - 每个 appId 请求一次
  externalDriverFactory: (context: RequestContext) => BaseDriver | Promise<BaseDriver>;

  // AppID - 每次请求
  // 缓存 Key - schema compilation results, connection pool 等
  // 例如 ({ securityContext }) => `CUBEJS_APP_${securityContext.tenantId}_${securityContext.user_id}`
  contextToAppId: (context: RequestContext) => string;
  // 查询编排缓存 Key - 默认为 appId - 每次请求
  // 数据库连接, 执行队列, 预聚合表缓存
  // 例如 ({ securityContext }) => `CUBEJS_APP_${securityContext.tenantId}`
  contextToOrchestratorId: (context: RequestContext) => string;
  // Schema 仓库 - 每 AppID 请求
  // 实现多租户不同 schema
  // 例如 ({ securityContext }) => new FileRepository(`schema/${securityContext.appId}`)
  repositoryFactory: (context: RequestContext) => SchemaFileRepository;
  // REST 和 WebSockets API 鉴权
  // 默认 检查 Authorization JWT,验证后内容设置为 req.securityContext
  // 可禁用 (req, auth) => {}
  checkAuth: (req: ExpressRequest, authorization: string) => any;
  // SQL API 鉴权 - 默认校验 CUBE_SQL_USERNAME, CUBE_SQL_PASSWORD
  checkSqlAuth: (req: SQLRequest, user: string) => any;
  // 查询执行前的额外检查
  queryRewrite: (query: object, context: RequestContext) => object;
  // 预聚合 schema - 推荐生产和开发使用不同 schema - 每个 appId 请求一次
  // 开发模式默认 dev_pre_aggregations
  // 生产模式默认 prod_pre_aggregations
  preAggregationsSchema: string | ((context: RequestContext) => string);
  // schema 版本 - 确定什么时候重新编译
  schemaVersion: (context: RequestContext) => string;

  scheduledRefreshTimer: boolean | number;
  scheduledRefreshTimeZones: string[];
  scheduledRefreshContexts: () => Promise<object[]>;

  // 扩展 RequestContext
  extendContext: (req: ExpressRequest) => any;
  // 默认 250
  compilerCacheSize: number;
  // 单位 ms
  maxCompilerCacheKeepAlive: number;
  updateCompilerCacheKeepAlive: boolean;
  allowUngroupedWithoutPrimaryKey: boolean;
  telemetry: boolean;

  http: {
    cors: {
      methods: string | string[];
      origin: string;
      allowedHeaders: string | string[];
      exposedHeaders: string | string[];
      credentials: boolean;
      maxAge: number;
      preflightContinue: boolean;
      optionsSuccessStatus: number;
    };
  };

  jwt: {
    jwkUrl?: ((payload: any) => string) | string;
    key?: string;
    algorithms?: string[];
    issuer?: string[];
    audience?: string;
    subject?: string;
    claimsNamespace?: string;
  };
  // 推荐生产使用 redis
  cacheAndQueueDriver: 'memory' | 'redis';
  // 推荐保留默认
  orchestratorOptions: OrchestratorOptions | ((context: RequestContext) => OrchestratorOptions);
  allowJsDuplicatePropsInSchema: boolean;
}

interface OrchestratorOptions {
  redisPrefix: string;
  rollupOnlyMode: bool;
  queryCacheOptions: {
    refreshKeyRenewalThreshold: number;
    backgroundRenew: boolean;
    queueOptions: QueueOptions;
  };
  preAggregationsOptions: {
    queueOptions: QueueOptions;
  };
}

interface QueueOptions {
  concurrency: number;
  continueWaitTimeout: number;
  executionTimeout: number;
  orphanedTimeout: number;
  heartBeatInterval: number;
}

interface RequestContext {
  securityContext: object;
  requestId: string;
}

interface DriverContext extends RequestContext {
  dataSource: string;
}

interface SchemaFileRepository {
  dataSchemaFiles(): Promise<FileContent[]>;
}

interface FileContent {
  fileName: string;
  content: string;
}
QueueOptions
{
  "concurrency": 2,
  "continueWaitTimeout": 5,
  "executionTimeout": 600,
  "orphanedTimeout": 120,
  "heartBeatInterval": 30
}

Multitenancy

  • Multitenancy vs Multiple Data Sources
    • Multitenancy
      • 多用户,不同数据集
    • Multiple Data Sources
      • 相同数据不同数据库
      • cube 关联 dataSource
      • 配置 dbType+driverFactory 生成多数据源
  • Security Context vs Multitenant Compile Context
    • Security Context
      • row-level security within the same database for different users
    • Multitenant Compile Context
      • access different databases
  • Security Context vs queryRewrite
    • Security Context
      • explicit control
cube.js
const PostgresDriver = require('@cubejs-backend/postgres-driver');

module.exports = {
  driverFactory: ({ dataSource }) => new PostgresDriver({ database: dataSource }),
};

数据库

JavaScript
const MySQLDriver = require('@cubejs-backend/mysql-driver');

new MySQLDriver({
  host: process.env.CUBEJS_EXT_DB_HOST,
  database: process.env.CUBEJS_EXT_DB_NAME,
  port: process.env.CUBEJS_EXT_DB_PORT,
  user: process.env.CUBEJS_EXT_DB_USER,
  password: process.env.CUBEJS_EXT_DB_PASS,
});

关联信息

反向链接、本文链接的其他页面和外部资料。

参考资料

其他外链3 条
最近更新commit 456b1b1编辑