downsampling-dsl.asciidoc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. [[downsampling-dsl]]
  2. === Run downsampling using data stream lifecycle
  3. ++++
  4. <titleabbrev>Run downsampling using data stream lifecycle</titleabbrev>
  5. ++++
  6. This is a simplified example that allows you to see quickly how
  7. <<downsampling,downsampling>> works as part of a datastream lifecycle to reduce the
  8. storage size of a sampled set of metrics. The example uses typical Kubernetes
  9. cluster monitoring data. To test out downsampling with data stream lifecycle, follow these steps:
  10. . Check the <<downsampling-dsl-prereqs,prerequisites>>.
  11. . <<downsampling-dsl-create-index-template>>.
  12. . <<downsampling-dsl-ingest-data>>.
  13. . <<downsampling-dsl-view-data-stream-state>>.
  14. . <<downsampling-dsl-rollover>>.
  15. . <<downsampling-dsl-view-results>>.
  16. [discrete]
  17. [[downsampling-dsl-prereqs]]
  18. ==== Prerequisites
  19. Refer to <<tsds-prereqs,time series data stream prerequisites>>.
  20. [discrete]
  21. [[downsampling-dsl-create-index-template]]
  22. ==== Create an index template with data stream lifecycle
  23. This creates an index template for a basic data stream. The available parameters
  24. for an index template are described in detail in <<set-up-a-data-stream,Set up a
  25. time series data stream>>.
  26. For simplicity, in the time series mapping all `time_series_metric` parameters
  27. are set to type `gauge`, but the `counter` metric type may also be used. The
  28. `time_series_metric` values determine the kind of statistical representations
  29. that are used during downsampling.
  30. The index template includes a set of static <<time-series-dimension,time series
  31. dimensions>>: `host`, `namespace`, `node`, and `pod`. The time series dimensions
  32. are not changed by the downsampling process.
  33. To enable downsampling, this template includes a `lifecycle` section with <<data-streams-put-lifecycle-downsampling-example, downsampling>> object. `fixed_interval` parameter sets downsampling interval at which you want to aggregate the original time series data. `after` parameter specifies how much time after index was rolled over should pass before downsampling is performed.
  34. [source,console]
  35. ----
  36. PUT _index_template/datastream_template
  37. {
  38. "index_patterns": [
  39. "datastream*"
  40. ],
  41. "data_stream": {},
  42. "template": {
  43. "lifecycle": {
  44. "downsampling": [
  45. {
  46. "after": "1m",
  47. "fixed_interval": "1h"
  48. }
  49. ]
  50. },
  51. "settings": {
  52. "index": {
  53. "mode": "time_series"
  54. }
  55. },
  56. "mappings": {
  57. "properties": {
  58. "@timestamp": {
  59. "type": "date"
  60. },
  61. "kubernetes": {
  62. "properties": {
  63. "container": {
  64. "properties": {
  65. "cpu": {
  66. "properties": {
  67. "usage": {
  68. "properties": {
  69. "core": {
  70. "properties": {
  71. "ns": {
  72. "type": "long"
  73. }
  74. }
  75. },
  76. "limit": {
  77. "properties": {
  78. "pct": {
  79. "type": "float"
  80. }
  81. }
  82. },
  83. "nanocores": {
  84. "type": "long",
  85. "time_series_metric": "gauge"
  86. },
  87. "node": {
  88. "properties": {
  89. "pct": {
  90. "type": "float"
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }
  97. },
  98. "memory": {
  99. "properties": {
  100. "available": {
  101. "properties": {
  102. "bytes": {
  103. "type": "long",
  104. "time_series_metric": "gauge"
  105. }
  106. }
  107. },
  108. "majorpagefaults": {
  109. "type": "long"
  110. },
  111. "pagefaults": {
  112. "type": "long",
  113. "time_series_metric": "gauge"
  114. },
  115. "rss": {
  116. "properties": {
  117. "bytes": {
  118. "type": "long",
  119. "time_series_metric": "gauge"
  120. }
  121. }
  122. },
  123. "usage": {
  124. "properties": {
  125. "bytes": {
  126. "type": "long",
  127. "time_series_metric": "gauge"
  128. },
  129. "limit": {
  130. "properties": {
  131. "pct": {
  132. "type": "float"
  133. }
  134. }
  135. },
  136. "node": {
  137. "properties": {
  138. "pct": {
  139. "type": "float"
  140. }
  141. }
  142. }
  143. }
  144. },
  145. "workingset": {
  146. "properties": {
  147. "bytes": {
  148. "type": "long",
  149. "time_series_metric": "gauge"
  150. }
  151. }
  152. }
  153. }
  154. },
  155. "name": {
  156. "type": "keyword"
  157. },
  158. "start_time": {
  159. "type": "date"
  160. }
  161. }
  162. },
  163. "host": {
  164. "type": "keyword",
  165. "time_series_dimension": true
  166. },
  167. "namespace": {
  168. "type": "keyword",
  169. "time_series_dimension": true
  170. },
  171. "node": {
  172. "type": "keyword",
  173. "time_series_dimension": true
  174. },
  175. "pod": {
  176. "type": "keyword",
  177. "time_series_dimension": true
  178. }
  179. }
  180. }
  181. }
  182. }
  183. }
  184. }
  185. ----
  186. ////
  187. [source,console]
  188. ----
  189. DELETE _index_template/*
  190. ----
  191. // TEST[continued]
  192. ////
  193. [discrete]
  194. [[downsampling-dsl-ingest-data]]
  195. ==== Ingest time series data
  196. Use a bulk API request to automatically create your TSDS and index a set of ten
  197. documents.
  198. **Important:** Before running this bulk request you need to update the
  199. timestamps to within three to five hours after your current time. That is,
  200. search `2022-06-21T15` and replace with your present date, and adjust the hour
  201. to your current time plus three hours.
  202. [source,console]
  203. ----
  204. PUT /datastream/_bulk?refresh
  205. {"create": {}}
  206. {"@timestamp":"2022-06-21T15:49:00Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":91153,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":463314616},"usage":{"bytes":307007078,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":585236},"rss":{"bytes":102728},"pagefaults":120901,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  207. {"create": {}}
  208. {"@timestamp":"2022-06-21T15:45:50Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":124501,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":982546514},"usage":{"bytes":360035574,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1339884},"rss":{"bytes":381174},"pagefaults":178473,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  209. {"create": {}}
  210. {"@timestamp":"2022-06-21T15:44:50Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":38907,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":862723768},"usage":{"bytes":379572388,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":431227},"rss":{"bytes":386580},"pagefaults":233166,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  211. {"create": {}}
  212. {"@timestamp":"2022-06-21T15:44:40Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":86706,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":567160996},"usage":{"bytes":103266017,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1724908},"rss":{"bytes":105431},"pagefaults":233166,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  213. {"create": {}}
  214. {"@timestamp":"2022-06-21T15:44:00Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":150069,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":639054643},"usage":{"bytes":265142477,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1786511},"rss":{"bytes":189235},"pagefaults":138172,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  215. {"create": {}}
  216. {"@timestamp":"2022-06-21T15:42:40Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":82260,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":854735585},"usage":{"bytes":309798052,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":924058},"rss":{"bytes":110838},"pagefaults":259073,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  217. {"create": {}}
  218. {"@timestamp":"2022-06-21T15:42:10Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":153404,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":279586406},"usage":{"bytes":214904955,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1047265},"rss":{"bytes":91914},"pagefaults":302252,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  219. {"create": {}}
  220. {"@timestamp":"2022-06-21T15:40:20Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":125613,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":822782853},"usage":{"bytes":100475044,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":2109932},"rss":{"bytes":278446},"pagefaults":74843,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  221. {"create": {}}
  222. {"@timestamp":"2022-06-21T15:40:10Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":100046,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":567160996},"usage":{"bytes":362826547,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1986724},"rss":{"bytes":402801},"pagefaults":296495,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  223. {"create": {}}
  224. {"@timestamp":"2022-06-21T15:38:30Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":40018,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":1062428344},"usage":{"bytes":265142477,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":2294743},"rss":{"bytes":340623},"pagefaults":224530,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
  225. ----
  226. // TEST[skip: timestamp values won't match an accepted range in the TSDS]
  227. [discrete]
  228. [[downsampling-dsl-view-data-stream-state]]
  229. ==== View current state of data stream
  230. Now that you've created and added documents to the data stream, check to confirm
  231. the current state of the new index.
  232. [source,console]
  233. ----
  234. GET _data_stream
  235. ----
  236. // TEST[skip: temporal_ranges and index names won't match]
  237. If the data stream lifecycle policy has not yet been applied, your results will be like the
  238. following. Note the original `index_name`: `.ds-datastream-2024.04.29-000001`.
  239. [source,console-result]
  240. ----
  241. {
  242. "data_streams": [
  243. {
  244. "name": "datastream",
  245. "timestamp_field": {
  246. "name": "@timestamp"
  247. },
  248. "indices": [
  249. {
  250. "index_name": ".ds-datastream-2024.04.29-000001",
  251. "index_uuid": "vUMNtCyXQhGdlo1BD-cGRw",
  252. "managed_by": "Data stream lifecycle"
  253. }
  254. ],
  255. "generation": 1,
  256. "status": "GREEN",
  257. "template": "datastream_template",
  258. "lifecycle": {
  259. "enabled": true,
  260. "downsampling": [
  261. {
  262. "after": "1m",
  263. "fixed_interval": "1h"
  264. }
  265. ]
  266. },
  267. "next_generation_managed_by": "Data stream lifecycle",
  268. "hidden": false,
  269. "system": false,
  270. "allow_custom_routing": false,
  271. "replicated": false,
  272. "rollover_on_write": false,
  273. "time_series": {
  274. "temporal_ranges": [
  275. {
  276. "start": "2024-04-29T15:55:46.000Z",
  277. "end": "2024-04-29T18:25:46.000Z"
  278. }
  279. ]
  280. }
  281. }
  282. ]
  283. }
  284. ----
  285. // TEST[skip: some fields are removed for brevity]
  286. // TEST[continued]
  287. Next, run a search query:
  288. [source,console]
  289. ----
  290. GET datastream/_search
  291. ----
  292. // TEST[skip: timestamp values won't match]
  293. The query returns your ten newly added documents.
  294. [source,console-result]
  295. ----
  296. {
  297. "took": 23,
  298. "timed_out": false,
  299. "_shards": {
  300. "total": 1,
  301. "successful": 1,
  302. "skipped": 0,
  303. "failed": 0
  304. },
  305. "hits": {
  306. "total": {
  307. "value": 10,
  308. "relation": "eq"
  309. },
  310. ...
  311. ----
  312. // TEST[skip: some fields are removed for brevity]
  313. // TEST[continued]
  314. [discrete]
  315. [[downsampling-dsl-rollover]]
  316. ==== Roll over the data stream
  317. Data stream lifecycle will automatically roll over data stream and perform downsampling. This step is only needed in order to see downsampling results in scope of this tutorial.
  318. Roll over the data stream using the <<indices-rollover-index,rollover API>>:
  319. [source,console]
  320. ----
  321. POST /datastream/_rollover/
  322. ----
  323. // TEST[continued]
  324. [discrete]
  325. [[downsampling-dsl-view-results]]
  326. ==== View downsampling results
  327. By default, data stream lifecycle actions are executed every five minutes. Downsampling takes place after the index is rolled over and the <<index-time-series-end-time, index time series end time>>
  328. has lapsed as the source index is still expected to receive major writes until then. Index is now rolled over after previous step but its time series range end is likely still in the future. Once index time series range is in the past, re-run the `GET _data_stream` request.
  329. [source,console]
  330. ----
  331. GET _data_stream
  332. ----
  333. // TEST[skip: temporal_ranges and index names won't match]
  334. After the data stream lifecycle action was executed, original
  335. `.ds-datastream-2024.04.29-000001` index is replaced with a new, downsampled
  336. index, in this case `downsample-1h-.ds-datastream-2024.04.29-000001`.
  337. [source,console-result]
  338. ----
  339. {
  340. "data_streams": [
  341. {
  342. "name": "datastream",
  343. "timestamp_field": {
  344. "name": "@timestamp"
  345. },
  346. "indices": [
  347. {
  348. "index_name": "downsample-1h-.ds-datastream-2024.04.29-000001",
  349. "index_uuid": "VqXuShP4T8ODAOnWFcqitg",
  350. "managed_by": "Data stream lifecycle"
  351. },
  352. {
  353. "index_name": ".ds-datastream-2024.04.29-000002",
  354. "index_uuid": "8gCeSdjUSWG-o-PeEAJ0jA",
  355. "managed_by": "Data stream lifecycle"
  356. }
  357. ],
  358. ...
  359. ----
  360. // TEST[skip: some fields are removed for brevity]
  361. // TEST[continued]
  362. Run a search query on the datastream (note that when querying downsampled indices there are <<querying-downsampled-indices-notes,a few nuances to be aware of>>).
  363. [source,console]
  364. ----
  365. GET datastream/_search
  366. ----
  367. // TEST[continued]
  368. The new downsampled index contains just one document that includes the `min`,
  369. `max`, `sum`, and `value_count` statistics based off of the original sampled
  370. metrics.
  371. [source,console-result]
  372. ----
  373. {
  374. "took": 26,
  375. "timed_out": false,
  376. "_shards": {
  377. "total": 2,
  378. "successful": 2,
  379. "skipped": 0,
  380. "failed": 0
  381. },
  382. "hits": {
  383. "total": {
  384. "value": 1,
  385. "relation": "eq"
  386. },
  387. "max_score": 1,
  388. "hits": [
  389. {
  390. "_index": "downsample-1h-.ds-datastream-2024.04.29-000001",
  391. "_id": "0eL0wMf38sl_s5JnAAABjyrMjoA",
  392. "_score": 1,
  393. "_source": {
  394. "@timestamp": "2024-04-29T17:00:00.000Z",
  395. "_doc_count": 10,
  396. "kubernetes": {
  397. "container": {
  398. "cpu": {
  399. "usage": {
  400. "core": {
  401. "ns": 12828317850
  402. },
  403. "limit": {
  404. "pct": 0.0000277905
  405. },
  406. "nanocores": {
  407. "min": 38907,
  408. "max": 153404,
  409. "sum": 992677,
  410. "value_count": 10
  411. },
  412. "node": {
  413. "pct": 0.0000277905
  414. }
  415. }
  416. },
  417. "memory": {
  418. "available": {
  419. "bytes": {
  420. "min": 279586406,
  421. "max": 1062428344,
  422. "sum": 7101494721,
  423. "value_count": 10
  424. }
  425. },
  426. "majorpagefaults": 0,
  427. "pagefaults": {
  428. "min": 74843,
  429. "max": 302252,
  430. "sum": 2061071,
  431. "value_count": 10
  432. },
  433. "rss": {
  434. "bytes": {
  435. "min": 91914,
  436. "max": 402801,
  437. "sum": 2389770,
  438. "value_count": 10
  439. }
  440. },
  441. "usage": {
  442. "bytes": {
  443. "min": 100475044,
  444. "max": 379572388,
  445. "sum": 2668170609,
  446. "value_count": 10
  447. },
  448. "limit": {
  449. "pct": 0.00009923134
  450. },
  451. "node": {
  452. "pct": 0.017700378
  453. }
  454. },
  455. "workingset": {
  456. "bytes": {
  457. "min": 431227,
  458. "max": 2294743,
  459. "sum": 14230488,
  460. "value_count": 10
  461. }
  462. }
  463. },
  464. "name": "container-name-44",
  465. "start_time": "2021-03-30T07:59:06.000Z"
  466. },
  467. "host": "gke-apps-0",
  468. "namespace": "namespace26",
  469. "node": "gke-apps-0-0",
  470. "pod": "gke-apps-0-0-0"
  471. }
  472. }
  473. }
  474. ]
  475. }
  476. }
  477. ----
  478. // TEST[skip: timestamp values won't match]
  479. // TEST[continued]
  480. Use the <<data-stream-stats-api,data stream stats API>> to get statistics for
  481. the data stream, including the storage size.
  482. [source,console]
  483. ----
  484. GET /_data_stream/datastream/_stats?human=true
  485. ----
  486. // TEST[continued]
  487. [source,console-result]
  488. ----
  489. {
  490. "_shards": {
  491. "total": 4,
  492. "successful": 4,
  493. "failed": 0
  494. },
  495. "data_stream_count": 1,
  496. "backing_indices": 2,
  497. "total_store_size": "37.3kb",
  498. "total_store_size_bytes": 38230,
  499. "data_streams": [
  500. {
  501. "data_stream": "datastream",
  502. "backing_indices": 2,
  503. "store_size": "37.3kb",
  504. "store_size_bytes": 38230,
  505. "maximum_timestamp": 1714410000000
  506. }
  507. ]
  508. }
  509. ----
  510. // TEST[skip: exact size may be different]
  511. // TEST[continued]
  512. This example demonstrates how downsampling works as part of a data stream lifecycle to
  513. reduce the storage size of metrics data as it becomes less current and less
  514. frequently queried.
  515. ////
  516. [source,console]
  517. ----
  518. DELETE _data_stream/*
  519. DELETE _index_template/*
  520. ----
  521. // TEST[continued]
  522. ////