一个人可以合理地从多少个仪表板中获得洞察并采取行动?虽然我不知道答案(实际上这将是一项很好的调查),但我希望我们都可以达成一致的看法,即存在一定的限制。当我们在分析问题本身之前就为每个问题创建一个仪表板,而不进行分析时,仪表板膨胀就会发生。
定义:仪表板膨胀是组织在寻找相关的可视化以回答问题或重新创建已存在的可视化时浪费时间的影响。
在这种情况下,成本是时间(因此效率)。当完美的Looker实例组织得很差时,增长负责人花更多时间寻找按付费用户与免费用户分割的CAC上的有用图形,而实际上并未改变增长策略。如果整洁和组织已经被丢弃,分析团队将重新创建已存在的可视化。
仪表板膨胀可能是自助策略实施不善的结果,也可能是自助策略的直接反面,这取决于你的观点。有些人自2013年以来一直在说仪表板不是答案,但在近10年后,它们仍然像以往一样被使用。虽然确实有新趋势,如数据应用程序、自动化洞察和操作化数据,但仪表板在很长一段时间内都不会消失。
在它们将继续存在的前提下,我们该如何组织它们呢?
他们说初创公司之所以获胜,是因为它们行动迅速,这也适用于初创公司中的分析团队。通常情况下,要做的事情太多,因此很难将策略置于持续执行一切和任何事情之上,直到技术债务已经存在。
假设有人在阅读本文时刚开始考虑BI工具策略,那么这一部分适合你。通常情况下,在快速前进并需要回溯步骤之前,才会讨论策略问题。在这种情况下,回答这些问题是关于你想要世界看起来的方式,而不是今天的样子。
只有通过回答关于你作为数据领导者如何设想组织内的BI看起来以及积极纠正以尽可能接近这一愿景,才能避免仪表板膨胀。
💡考虑整体分析策略。
💡用BI的游戏规则具体化。
对于这些问题的答案会因公司规模(50人还是500人?)、文化(中央化还是分散化的分析团队?)、业务类型(B2B还是B2C?)等而异。然而,最后一个问题是最重要的。
让我们从头开始:这是我开始的基本战略。
分析策略
BI实例组织
作为数据专业人士,我们都曾经经历过一个被宣称为任务关键的要求。他们说美在于看的人的眼睛,关键性也是如此。然后,当我们发现每隔15分钟更新一次的仪表板实际上并没有被使用时,当然,可以将其删除一次。但是,有什么阻止同样的问题再次发生呢?
策略只有在维护良好时才能发挥作用,而维护的一个关键部分是弃用。
虽然在公司内部,人工质量保证可能是最政治正确的方法,但它是最手动和最难以优先考虑的方法。我提议建立一种自动化的仪表板弃用策略,它只需构建一次并需要极少的人工支持。
自动化的仪表板弃用策略会获取所有的BI元数据,并自动删除长时间未使用的可视化。
我将通过Python伪代码示例来进行详细介绍,以Looker为例,因为它非常流行并且容易出现冗余,同时还将提供其他企业工具的指南(因为几乎任何BI工具都可以执行此操作)。
让我们进入技术细节。
初始化访问实例。在Looker中,可以通过Python SDK来实现这一点。设置实例的URL、客户端ID和客户端密钥的环境变量。其他BI工具可能也有官方SDK(例如Tableau),其他工具可能有非官方SDK(例如Domo),或者你可能会发现直接调用REST API(例如PowerBI)更方便。
import looker_sdk
sdk = looker_sdk.init31()
通过SDK直接获取所有可能的数据。对于Looker来说,最有用的信息是获取所有的仪表板、查询和用户。对于Tableau Server,获取工作簿、视图和用户。无论使用哪种BI工具,都需要通过将其转换为JSON或提取与相关性特定字段(如ID、名称、创建日期、用户)的方式来清理响应。
dashboards = sdk.all_dashboards()
looks = sdk.all_looks()
users = sdk.all_users()
从内部使用统计报告中获取数据。许多工具不会直接通过API公开使用情况和历史数据。但是,它们会公开原始数据集,比如Looker(i__looker metadata)和PowerBI(原始审计日志),或者Tableau和Domo中的预构建报告。任何任意的BI报告本身都可以在Python中导出为数据集。我们实际上只需要一个包含每个可视化的最新访问日期的报告。
history_data = sdk.run_look(my_admin_look_id, result_format="json")
将所有这些输出写入数据仓库表格。我不会为此提供代码片段。覆盖具有数据导出(如所有可视化)的表格,并附加随时间积累的数据(如历史访问)。这个过程应该是幂等的,并按计划运行(我建议每天运行),以实现完全自动化。
无论你选择如何转换数据,原始表格都需要连接、透视和聚合才能有意义。
让我们回顾一下我们拥有的数据源:
我们需要的结果是一个表格,每个可视化对应一行,其中包括它的创建时间、创建它的用户以及最后一次查看或编辑的日期。一个粗略的查询可能如下所示:
with history as (
select visual_id,
max(access_date) as latest_access_date
from looker_historical_access
group by visual_id
), dashboards as (
select
id as visual_id,
name as visual_name,
user_id as visual_created_user_id,
created_at as visual_created_at,
'dashboard' as type
from dashboard
), looks as (
select
id as visual_id,
name as visual_name,
user_id as visual_created_user_id,
created_at as visual_created_at,
'look' as type
from look
), visuals as(
select * from dashboards union all select * from looks
)
select
v.*,
coalesce(h.latest_access_date, v.visual_created_at) as latest_access_date,
u.email
from visuals as v
left join history as h on h.visual_id =
left join user as u on v.visual_created_user_id;
有一些事情没有详细介绍:
因此,我们已经将所有数据存储在数据仓库中,并且知道哪些可视化最近没有被使用(我通常建议将“不常用”的门槛设置为60或90天)。BI工具通常在数据团队之外被广泛使用,那么如何进行这一努力的沟通呢?
传达努力的原因。组织内部的沟通总是最困难的一步。在开始弃用努力之前,要记录并传达保持清洁的BI实例对整个组织的好处(…或者如果你愿意的话,可以传阅本文)。目的不是删除其他人的工作,而是使公司中的每个人能够更快地从数据中获取洞察。
为自动通信创建一个弃用的Slack频道。任何使用BI工具的用户都应该被添加到这个频道中。
查询最近X-7天内未访问的可视化并发送Slack消息。包括未使用53天(如果在60天空闲时间后删除)或83天(如果在90天空闲时间后删除)的可视化。为每个可视化发送一个Slack消息,标记创建它的用户。
# Everything below is pseudo-code, with utility methods abstracted away
deprecation_days = 60
warn_visuals = get_warehouse_data( # Pseudo method
f'''
select visual_name, created_by_user
from modeled_looker_data
where current_date - last_accessed_date = {deprecation_days - 7}
''')
slack_message_template = '''
Visual {{visual_name}} created by @{{slack_username}} will be
deprecated in 7 days. If this is incorrect, please contact the
analytics team.
'''
for visual in warn_visuals:
send_slack_message(slack_message_template, visual) # Pseudo method
查询准备删除的可视化并以编程方式删除它们。在获取准备删除的可视化列表之后,你将不得不对每个可视化进行迭代,并删除每个可视化。在迭代过程中,可能会针对不同类型的可视化使用不同的方法。类型可以在建模数据时存储,以在此步骤中使用。每个可视化都应该先收到警告消息。
deprecation_days = 60
delete_visuals = get_warehouse_data( # Pseudo method
f'''
select visual_id
from modeled_looker_data
where current_date - last_accessed_date >= {deprecation_days}
''')
for visual in delete_visuals:
visual_id = visual['visual_id']
if visual['type'] == 'look':
sdk.delete_look(visual_id)
else:
sdk.delete_dashboard(visual_id)
正如木工所说:“量好两次,切一次”。当涉及删除事物时,运行自动化过程几周,注释掉实际删除以确保逻辑正确。
这篇文章的标题是有目的的:我们发现清理工作令人兴奋,包括自动清理BI实例。人们说,当你的工作空间整洁时,生产力会提高,那么为什么你的BI实例不应该也一样整洁呢?
最后,如果我不再提供一些建议,我将感到遗漏。
大多数企业工具没有免费层级,这就是为什么提供了一个大致的代码概要,而没有提供具体的代码片段,因为这些代码片段很难持续测试。还没有提到新的或代码重的BI工具,比如Superset、Lightdash、Metabase等等。虽然建议无论使用什么工具都采用这种方法,但API中公开的具体端点可能会有所不同。
需要提到数据目录在元数据工作中的作用。虽然大多数现代数据目录连接到BI工具并为你收集元数据,但它们还没有建立起主动删除可视化的机制(尚未)。然而,在过渡期间,一个中间地带可能是直接从集中式数据目录导出BI元数据,并自己编写弃用逻辑。这种方法仍然需要处理API等内容。