1. История
В настоящее время уровень приоритета индикаторов доставки в реальном времени, предоставляемых хранилищами данных в реальном времени, становится все более важным. В частности, данные хранилища данных, предоставляемые нижестоящими механизмами правил, оказывают непосредственное влияние на доставку рекламы рекламных операций. Задержки или отклонения данных могут привести к прямым или косвенным потерям активов.Потеря;Судя по панораме каналов платформы управления доставкой, текущая доставка представляет собой операционный процесс с замкнутым циклом.Хранилище данных в реальном времени является ключевым узлом в канале передачи данных. Данные в реальном времени напрямую поддерживают автоматическую работу механизма правил и доставки. Ручное управление платформой управления; аварии узлов в реальном времени могут привести к сбою в нормальной работе всего канала доставки; для достижения стабильности 99,9% звена доставки необходимо улучшить стабильность и приоритетность задач звена.
Комплексный план оценки испытаний НИОКР добавляет резервную ссылку к действующей ссылке, повторяет требования к доставке и вносит итерационные изменения через резервную ссылку.После завершения модификации выполняется Diff основного и резервного каналов, чтобы гарантировать, что Diff пройдет ставка составляет 99,9%, и тогда он может выйти в Интернет.
2. План реализации
-
Подготовка данных: данные, генерируемые активными и резервными каналами, записываются в ODPS в режиме реального времени.
-
Сбор данных. Служба инструмента тестирования одновременно собирает фрагменты данных активного и резервного канала, сохраняя 2 копии данных за один и тот же период времени.
-
Снижение шума данных и разница: после того, как инструмент соберет данные, он выполнит первый этап обработки шумоподавления; основные и резервные данные начнут сравниваться и второй этап обработки шумоподавления.
-
Результат сравнения данных: Обработайте результат сравнения данных, определите разницу в каждом поле и, наконец, определите разницу в общих данных и выдайте результат.
3. Настройте основные и резервные каналы связи.
Объяснение ссылки в режиме реального времени: исходные данные записываются в Kafka, Flink использует данные Kafka в качестве источника данных (источник), объединяет поля атрибутов для выполнения операторской обработки (Transformatin), а результаты обработки записываются в Kafka (приемник). для следующего этапа обработки. Обработка передается в базу данных приложения через каждый узел задачи Flink.
4. Подготовка данных – нарезка данных
Срез временного окна
Разрежьте в соответствии с моментом времени тестирования и зафиксируйте данные от 0 часов дня до периода времени выполнения, чтобы гарантировать, что данные больше не обновляются.
Нарезка бизнес-сценариев
Различные бизнес-сценарии итеративно нарезаются на срезы, и поток данных доставляется для предоставления различных данных последующих сценариев. Срезы фиксируются для итерированных данных бизнес-сценария. Например: field_a='b'
5. Данные активного и резервного канала.
Проблема с дрейфом данных
Признак: поток данных постоянно обновляется.Поток данных тех же бизнес-данных обновляется до последней версии.Основная ссылка может войти в раздел дня, а резервная ссылка может войти в раздел следующего дня.
План шумоподавления: возьмите последний фрагмент данных из потока данных.
Проблема с частотой обновления данных
Признак: во время процесса обновления одних и тех же бизнес-данных основная ссылка может быть обновлена 10 раз, данные не будут изменены в течение следующих пяти раз, а резервная ссылка будет обновлена только 5 раз.
Решение для шумоподавления: возьмите N фрагментов данных из потока данных для одних и тех же бизнес-данных.
Проблема со своевременностью обновления данных
Проблемное явление: во время одного и того же процесса обновления бизнес-данных основная ссылка обновляет три данных до 11.68, 12.9 и 13.05; резервная ссылка обновляет три данных до 11.68, 12.9 и 13.1; видно, что данные обновляются в следующем время уже не то же самое.
Решение для шумоподавления: потоки данных одних и тех же бизнес-данных объединяются в список, и ведущее и ведомое устройства взаимно определяют, существуют ли последние данные в списке потоков данных, перехваченных другой стороной.
Проблема несогласованных значений полей атрибутов
Признак: есть пустые символы, ноль, 0 и 0,0.Результат сравнения не удался, но фактическое бизнес-значение в порядке.
Решение для шумоподавления: разница после унифицированного преобразования.
Проблема несогласованности полей атрибутов синтаксического анализа поля сообщения активного и резервного каналов связи.
Признак: в поле сообщения хранятся данные в формате JSON. Для одного и того же фрагмента бизнес-данных поля атрибутов, соответствующие JSON, анализируемому первичной и вторичной ссылками, не полностью согласованы, и между ними существуют различия.
Решение для шумоподавления: проанализировать все поля атрибутов с помощью кода, чтобы обеспечить полный Diff.
шаблон сообщения:
{"fields_a":"20230628","fields_b":"2023-06-22 19:48:24","fields_c":"2","fields_d":"plan","fields_e":"3******","fields_f":"0.0","fields_g":"2","fields_h":"4*****","fields_i":"ext","fields_j":"binlog+odps","fields_k":"2","fields_l":"STATUS_*****","fields_m":"1********","fields_n":"孙**","fields_o":"2023-06-28T22:19:43.872"}
Конвертировать JSON:
{
"fields_a": "20230717",
"fields_d": "plan",
"fields_e": "3******",
"fields_aj": "33761.125",
"fields_p": "37934.0",
"fields_r": "1250.412",
"fields_s": "1250.412",
"fields_t": "33761.125",
"fields_w": "33761.125",
"fields_m": "1*********",
"fields_v": "33761.125",
"fields_y": "33761.125",
"fields_n": "孙**",
"fields_z": "1250.412",
"fields_ai": "27",
"fields_ak": "",
"fields_aa": "33761.125",
"fields_ab": "33761.125",
"fields_ac": "33761.0",
"fields_al": "0.1002",
"fields_i": "***",
"fields_j": "***",
"fields_k": "2",
"fields_ad": "1.0",
"fields_ak": "37934.0",
"fields_x": "1250.412",
"fields_y": "0.0",
"fields_ag": "27",
"fields_af": "27",
"fields_ah": "0.0",
"fields_al": "0.0",
"fields_am": "0.0",
"fields_ao": "37934.0",
"fields_ap": "37934.0",
"fields_an": "33761.125",
"fields_aq": "1*********",
"fields_ae": "27",
"fields_o": "2023-07-17T23:59:00.103",
"fields_ar": "0.1002"
}
Вышеупомянутые пять проблем можно устранить с помощью SQL. Общий шаблон SQL для шумоподавления выглядит следующим образом:
SET odps.sql.mapper.split.size = 64;
SET odps.stage.joiner.num = 4000;
SET odps.stage.reducer.num = 1999;
CREATE TABLE table_diff AS
SELECT a.fields_as AS fields_as_main
,b.fields_as AS fields_as_branch
,a.fields_at AS fields_at_main
,b.fields_at AS fields_at_branch
,a.fields_d AS fields_d_main
,b.fields_d AS fields_d_branch
,a.fields_i AS fields_i_main
,b.fields_i AS fields_i_branch
,a.fields_j AS fields_j_main
,b.fields_j AS fields_j_branch
,a.fields_aw AS fields_aw_main
,b.fields_aw AS fields_aw_branch
,a.fields_k_json_key AS fields_k_json_key_main
,b.fields_k_json_key AS fields_k_json_key_branch
,a.fields_k_json_key_list AS fields_k_json_key_list_main
,b.fields_k_json_key_list AS fields_k_json_key_list_branch
,CASE WHEN a.fields_k_json_key = b.fields_k_json_key THEN 0
WHEN b.fields_k_json_key_list RLIKE a.fields_k_json_key THEN 0
WHEN a.fields_k_json_key_list RLIKE b.fields_k_json_key THEN 0
ELSE 1
END AS fields_k_json_key_diff_flag
FROM (
SELECT fields_as
,fields_at
,fields_d
,fields_i
,fields_j
,fields_aw
,MAX(CASE WHEN rn = 1 THEN fields_k_json_key END) AS fields_k_json_key
,CONCAT_WS(',',COLLECT_SET(fields_k_json_key)) AS fields_k_json_key_list
FROM (
SELECT *
,CASE WHEN NVL(GET_JSON_OBJECT(message,'$.fields_k'),'') = '' THEN '---'
WHEN GET_JSON_OBJECT(message,'$.fields_k') IN ('0','0.0') THEN '0-0-0'
ELSE GET_JSON_OBJECT(message,'$.fields_k')
END AS fields_k_json_key
,ROW_NUMBER() OVER (PARTITION BY fields_as,fields_at,fields_d,fields_i,fields_j,fields_aw ORDER BY offset DESC ) AS rn
FROM table_main
WHERE pt = 20230628
-- AND fields_i = 'realMetric'
)
WHERE rn < 6
GROUP BY fields_as
,fields_at
,fields_d
,fields_i
,fields_j
,fields_aw
) a
LEFT JOIN (
SELECT fields_as
,fields_at
,fields_d
,fields_i
,fields_j
,fields_aw
,MAX(CASE WHEN rn = 1 THEN fields_k_json_key END) AS fields_k_json_key
,CONCAT_WS(',',COLLECT_SET(fields_k_json_key)) AS fields_k_json_key_list
FROM (
SELECT *
,CASE WHEN NVL(GET_JSON_OBJECT(message,'$.fields_k'),'') = '' THEN '---'
WHEN GET_JSON_OBJECT(message,'$.fields_k') IN ('0','0.0') THEN '0-0-0'
ELSE GET_JSON_OBJECT(message,'$.fields_k')
END AS fields_k_json_key
,ROW_NUMBER() OVER (PARTITION BY fields_as,fields_at,fields_d,fields_i,fields_j,fields_aw ORDER BY offset DESC ) AS rn
FROM table_branch
WHERE pt = 20230628
-- AND fields_i = 'realMetric'
and fields_d !='group'
)
WHERE rn < 6
GROUP BY fields_as
,fields_at
,fields_d
,fields_i
,fields_j
,fields_aw
) b
ON NVL(a.fields_as,'-00') = NVL(b.fields_as,'-00')
AND NVL(a.fields_at,'-00') = NVL(b.fields_at,'-00')
AND NVL(a.fields_d,'-00') = NVL(b.fields_d,'-00')
AND NVL(a.fields_i,'-00') = NVL(b.fields_i,'-00')
AND NVL(a.fields_j,'-00') = NVL(b.fields_j,'-00')
AND NVL(a.fields_aw,'-00') = NVL(b.fields_aw,'-00')
;
Проблема с шумоподавлением поля
Признак: при изменении логики поля результат Diff неверен, что влияет на результат Diff.
Решение по шумоподавлению: Необходимо отказаться от логически модифицированных полей, больше не судить о логически модифицированных полях и гибко управлять ими через Java.
String[] jsonColumnListStrings = jsonColumnList.split(",");
List<String> jsonColumnLists = new ArrayList<String>();
String[] iterationColumnStrings = iterationColumn.split(",");
List<String> iterationColumnLists = Arrays.asList(iterationColumnStrings);
for (String s:jsonColumnListStrings){
if(!iterationColumnLists.contains(s)){//判断字段是否为去噪字段
jsonColumnLists.add(s);
}
}
6. Анализ результатов различий
На основе SQL, синтезированного активным и резервным Diff, можно создать сравнительную таблицу результатов, а анализ результатов выполнения может определить, прошло ли выполнение или нет.
Логика анализа 1: Определите долю прохождения каждого поля сравнения
Проведите анализ исследований и разработок, в которых проанализированные поля имеют низкий процент прохождения.
Логика анализа 2. Определите долю всех полей, передающих общее количество записей.
Этот индикатор может определить, прошел ли Diff.Если он составляет 99,9%, это означает, что он прошел.
Проанализируйте образец SQL:
SELECT round(SUM(CASE WHEN fields_k_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_k_ratio
,round(SUM(CASE WHEN fields_m_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_m_ratio
,round(SUM(CASE WHEN fields_e_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_e_ratio
,round(SUM(CASE WHEN fields_a_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_aratio
,round(SUM(CASE WHEN fields_n_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_n_ratio
,round(SUM(CASE WHEN fields_p_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_p_ratio
,round(SUM(CASE WHEN fields_ac_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_ac_ratio
,round(SUM(CASE WHEN fields_ar_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS fields_ar_ratio
,round(SUM(CASE WHEN fields_k_json_key_diff_flag = 0 AND fields_m_json_key_diff_flag = 0 AND fields_e_json_key_diff_flag = 0 AND fields_a_json_key_diff_flag = 0 AND fields_n_json_key_diff_flag = 0 AND fields_p_json_key_diff_flag = 0 AND fields_ac_json_key_diff_flag = 0 AND fields_ar_json_key_diff_flag = 0 THEN 1 ELSE 0 END) / COUNT(1) * 100,4) AS total_ratio
,COUNT(1) AS total_cnt
FROM table_diff
;
7. Сервисизация инструмента
Логика обработки серверной службы
Первичное и вторичное сравнение SQL-синтеза
Внедрите SQL-код Diff в код, управляйте нарезкой данных, шумоподавлением и другими сценариями с помощью кода, чтобы завершить тестовый синтез SQL.
for(String s:jsonColumnLists){
selectSql1 = selectSql1 + " case when NVL(GET_JSON_OBJECT(message,'$." + s + "'),'')='' then '---' when get_json_object(message,'$." + s + "') in ('0','0.0') then '0-0-0' else get_json_object(message,'$." + s + "') end AS " + s + "_json_key,";
selectSql2 = selectSql2 + " max(case when rn =1 then " + s + "_json_key end) as " + s + "_json_key,concat_ws(',',collect_set(" + s + "_json_key)) as " + s + "_json_key_list,";
mergeSql = mergeSql + " a." + s + "_json_key as " + s + "_json_key_main,b." + s + "_json_key as " + s + "_json_key_branch,a." + s + "_json_key_list as " + s + "_json_key_list_main,b." + s + "_json_key_list as " + s + "_json_key_list_branch,case when a." + s + "_json_key = b." + s + "_json_key then 0 when b." + s + "_json_key_list rlike a." + s + "_json_key then 0 when a." + s + "_json_key_list rlike b." + s + "_json_key then 0 else 1 end as " + s + "_json_key_diff_flag,";
}
rowNumberSql ="ROW_NUMBER() OVER (PARTITION BY fields_as,fields_at,fields_d,fields_i,fields_j,fields_aw ORDER BY offset DESC ) AS rn ";
selectSql1 = selectSql1 + rowNumberSql;
whereSql1 = whereSql1 + bizdate + " AND fields_i = 'realMetric' ";
String pretreatmentSqlMain = "";
String pretreatmentSqlBranch = "";
pretreatmentSqlBranch = selectSql2.substring(0,selectSql2.length()-1) + " from(" + selectSql1 + " from " + branchLinkTableName + whereSql1 + ")" + whereSql2 + groupSql.substring(0,groupSql.length()-1);
pretreatmentSqlMain = selectSql2.substring(0,selectSql2.length()-1) + " from(" + selectSql1 + " from " + masterLinkTableName + whereSql1 + ")" + whereSql2 + groupSql.substring(0,groupSql.length()-1);
mergeSql = mergeSql.substring(0,mergeSql.length()-1) + " from (" + pretreatmentSqlMain + ")a left join (" + pretreatmentSqlBranch + ")b " + joinSql.substring(0,joinSql.length()-3) + ";";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String dateStr = simpleDateFormat.format(new Date());
this.resultDataCreateSql = "set odps.sql.mapper.split.size=64;set odps.stage.joiner.num=4000;set odps.stage.reducer.num=1999; create table du_temp.diff_main_branch_" + dateStr + "_test as " + mergeSql;
log.info(resultDataCreateSql);
this.resultDataTable = "du_temp.diff_main_branch_" + dateStr + "_test";
log.info(resultDataTable);
//合成过滤结果数据的sql
String resultSql = " select ";
String totalResultSql = "round(sum(case when ";
for(String s:jsonColumnLists){
resultSql = resultSql + " round(sum(case when " + s + "_json_key_diff_flag = 0 then 1 else 0 end)/count(1)*100,4) as " + s + "_ratio,";
totalResultSql = totalResultSql + " " + s + "_json_key_diff_flag = 0 and";
}
this.resultDataFiltrate = resultSql + totalResultSql.substring(0,totalResultSql.length()-3) + " then 1 else 0 end)/count(1)*100,4) as total_ratio , count(1) as total_cnt from " + this.resultDataTable + ";";
log.info(resultDataFiltrate);
Анализ отчета о результатах различий
...}
else if(testType.equals("主备diff")) {
for (Map.Entry entry:testResultRecord.entrySet()) {
List<String> listValue = (List<String>) entry.getValue();
this.resultData.put(entry.getKey().toString(),listValue.get(0)) ;
if(Double.parseDouble(listValue.get(0))< 99.9 & !entry.getKey().toString().equals("total_cnt")){
this.failDetail.put(entry.getKey().toString(),listValue.get(0)) ;
}
}
if(failDetail.size()>0){
this.testStatus = "失败";
}else {
this.testStatus = "成功";
}
}
Визуализация платформы
- Создать задачу
- список выполнения
- Отчет о результатах — отображение платформы
Как показано ниже: в результате сбоя выполнения процент прохождения составляет 99,8471, что не достигает 99,99% .
- Отчет о результатах — уведомление Feishu
Вот пример:
Имя требования выполнения: Active-backup Diff-521 Исполнитель: *** Тип выполнения: Active-backup Diff Номер выполнения: 20230628204636 Имя таблицы ссылок резервного копирования: table_main Имя таблицы основной ссылки выполнения: table_branch Раздел таблицы ссылок резервного копирования: 20230628 Подробности результата выполнения таблица: table_diff Сводка сведений о результатах выполнения:fields_am_ratio:99.9958fields_z_ratio:99.9826fields_af_ratio:99.9856fields_ba_ratio:99.9964fields_al_ratio:99.9915fields_ad_ratio:99.9873fields_r_ratio:99.9826fields_aa_ratio:99.99 06 полей_ai_ratio:99,9856 полей_v_ratio:99,9917 полей_ak_ratio:99,9909 полей_m_ratio:99,9969 полей_ak_ratio:99,9945 полей_bb_ratio :99.9964 fields_bc_ratio:99.9957 fields_bd_ratio:99.9954 fields_ae_ratio:99.9856 fields_be_ratio:99.9952 fields_bf_ratio:99.9955 fields_t_ratio:99.9917
fields_ag_ratio:99.9856 fields_p_ratio:99.9909 fields_bg_ratio:99.9948 fields_a_ratio:99.9969 fields_d_ratio:99.9969 fields_x_ratio:99.9826 fields_an_ratio:99.9917
fields_ap_ratio:99.9909 fields_ar_ratio:99.9915 fields_y_ratio:99.9917 fields_bh_ratio:99.9955 fields_aj_ratio:99.9916 fields_bi_ratio:99.987 fields_ac_ratio:99.9908 fields_s_ratio:99.9826 fields_ab_ratio:99.9906 fields_i_ratio:99.9969 fields_bj_ratio:99.9951 fields_ah_ratio:99.9959
fields_k_ratio:99.9969
fields_e_ratio:99.9969 fields_bk_ratio:99.9962 fields_bl_ratio:99.8748 fields_al_ratio:99.9958 fields_j_ratio:99.9969
fields_bm_ratio:99.9951 fields_n_ratio: 99,9969fields_ao_ratio:99,9909fields_w_ratio:99,9906fields_bn_ratio:99,9965fields_bo_ratio:99,9912fields_bcrate_ratio:99,987fields_y_ratio:99,9958 Сводные данные активных и резервных результатов выполнения различий: total_ratio:99,8471 total_cnt:71 42 59
Подробности об ошибке результата выполнения:
fields_bl_ratio :99.8748
total_ratio:99.8471% Результат выполнения статус: не удалось
8. Процесс доступа и выпуска активных и резервных инструментов сравнения.
Когда развернутая резервная линия наконец пройдет проверку активных и резервных инструментов Diff, она будет подключена к сети. В настоящее время это эквивалентно резервной производственной линии.
Для последующих итераций версий, если требования проверяются инструментом Diff перед подключением к сети, они будут соответствовать онлайн-требованиям.
9. Резюме
Вычисления в реальном времени отличаются от автономных хранилищ данных. Стабильность и точность данных трудно контролировать. Сложные ссылки не могут гарантировать качество общих данных посредством простого тестирования. Форма двухканального Diff может лучше гарантировать данные в реальном времени. во время итераций.качество.
Для реализации активного и резервного Diff: самой большой проблемой часто является то, что шум данных очень велик, что требует технических средств для уменьшения шума, чтобы обеспечить точность и надежность результатов сравнения данных.
* Текст/Шию
Автор этой статьи принадлежит Dewu Technology. Другие интересные статьи можно найти на официальном сайте Dewu Technology.
Перепечатка без разрешения Dewu Technology строго запрещена, в противном случае будет наступать юридическая ответственность в соответствии с законом!
Broadcom объявила о прекращении существующей партнерской программы VMware . Сайт B дважды выходил из строя, инцидент Tencent "3.29" первого уровня... Подводя итоги десяти крупнейших инцидентов с простоями в 2023 году, выпущен Vue 3.4 "Slam Dunk", Yakult подтвердил утечку данных 95G MySQL 5.7, Moqu, Li Tiaotiao... Подведение итогов проектов и веб-сайтов с открытым исходным кодом, которые будут «остановлены» в 2023 году. Официально выпущен «Отчет разработчиков открытого исходного кода Китая за 2023 год». Оглядываясь назад на IDE 30 лет назад: только TUI, яркий цвет фона…… Официально выпущена Julia 1.10 Выпущена Rust 1.75.0 NVIDIA выпустила GeForce RTX 4090 D специально для продажи в Китае