This change corrects the improper rendering of nanosecond walltime
event timestamps in the text profile section of imported query profiles.
The timestamps are now displayed in minutes and seconds, instead of
being displayed in date format. (i.e. 2s120ms, 2ms498us)
The navbar rendering from incorrect declaration in webUI ES6 refactor
IMPALA-13389 has also been corrected.
Incorrectly added columns "Coordinator Slots" and "Executor Slots" in
IMPALA-13726: Add admission control slots to /queries page in webui
have been removed from the imported query profile section.
Change-Id: Id1ad10f469aec085e5b485b4c20d6ab89fe58034
Reviewed-on: http://gerrit.cloudera.org:8080/23067
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Currently, the scripts in the entire webUI contain variable and function
declarations using the ES5 standard.
In such declarations, all the variables are attached to the browser's
window object, polluting the global scope. Additionally, many unnamed
functions can be represented with cleaner and concise syntax.
This patch refactors such declarations, using the ES6 syntax.
-> Replacing 'var' declarations with 'let' and 'const'
- To improve browser's memory utilization
- For better scoping, immutability and readability
-> Replacing unnamed function declarations with arrow functions
- Better scoping by binding 'this' object to the surrounding context
These improve maintainability and browser's memory utilization.
Across many instances within the webUI scripts, no particular naming
scheme is being followed for variable and function identifiers.
Hence, they have been revised with the following naming scheme.
-> All function names have been declared using camel case.
-> All constant primitive values and strings have been declared
in uppercase.
-> All other types of variables have been declared using snake case.
This naming scheme allows easier distinction between functions,
constants and other variables, based on the identifiers.
These changes to code style are further enforced during code review
through IMPALA-13473.
Change-Id: Ie38f2c642ede14956a2c6d551a58e42538204768
Reviewed-on: http://gerrit.cloudera.org:8080/21851
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
When tracking resource utilization it is useful to see how many
admission control slots are being used by queries. Add the slots used
by coordinator and executors to the webui queries tables. For
implementation reasons this entails also adding these fields to the
query history and live query tables.
The executor admission control slots are calculated by looking at a
single executor backend. In theory this single number could be
misleading but in practice queries are expected to have symmetrical
slots across executors.
Bump the schema number for the query history schema, and add some new
tests.
Change-Id: I057493b7767902a417dfeb75cdaeffd452d66789
Reviewed-on: http://gerrit.cloudera.org:8080/22443
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Representing phases of multiple instances in a single bar with dividers
makes it challenging to distinguish between the perimeters of each
instance's phases, hindering other instances that have already started
with the subsequent phase. Hence, the correlation between the recorded
profile metrics and the user's desired representation is less.
To improve this representation, the phases of each fragment's instances
are now being aggregated and displayed as a histogram on the timeline,
making it easier to understand the distribution of start time and
end time of different instance's phases.
When there are more than 5 instances for a phase, respective timestamps
are bucketed into 5 divisions, each spanning 20% of the difference
between maximum and minimum timestamp value. Each division's timestamps
are aggregated and then maximum value is plotted on the query timeline.
The height of each division's phase rectangle is proportional to
the number of instances in that division. A division without
any instances is not represented.
If the number of instances are less than or equal to 5, for each event,
instance timestamps are sorted in ascending order before plotting.
This results in a descending staircase form of aggregated metrics
display, where maximum timestamps within each of the 20% spanning
divisions is shown.
The precision of SVG elements' position and dimensions have been limited
and are set by the user. They will have the same precision as that of
the timeticks.
The order of rendering phases and iterating through colors for each
plan node has been reversed, in order to support this representation.
A tooltip containing the following additional details is displayed,
when hovering on a plane node's bucketed phase rectangle.
- With respect to the hovered on bucketed phase rectangle
- No. of instances
- Event's Maximum Timestamp (in seconds)
- Event's Minimum Timestamp (in seconds)
- Event's Average Timestamp (in seconds)
Outlines are drawn at the top and bottom of each plan node, according to
the timestamp of the instances' final closing phase.
The attribute 'stroke-dasharray' has been used to add separators between
the perimeters of each instance's phases, instead of an additional
SVG line element each time.
Redundant calls to 'appendChild' methods and setting fragment's ID
after each iteration have been removed.
With this approach, the number of SVG elements in the fragment diagram
is reduced substantially, resulting in very fast rendering times.
Similar to "HASH_JOIN_NODE", the rendering of 2nd and 3rd events
("Waiting for initial build" and "Initial build available")
for the node type "NESTED_LOOP_JOIN_NODE" have also been skipped.
Replaced equality operators with strict equality operators.
Manually tested with various profiles, sizes ranging from 4MB to 430MB.
Change-Id: Ied8a5966e9e4111bf7aa25aee11d23881daad7d2
Reviewed-on: http://gerrit.cloudera.org:8080/21593
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
This patch qualified some urls in template files.
Testing:
- Manully checked importing json profiles worked correctly with the
fix.
- Added new regex checks to test_knox_compatibility.
Change-Id: If53947c3b8429840990b361a936ba31e1df21522
Reviewed-on: http://gerrit.cloudera.org:8080/21574
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
On clicking the "X" button beside the imported query profiles
section header, deleting the entire "imported_profiles" database
and recreating it instead of clearing the "profiles" object store
would be more beneficial.
This could potentially resolve problems with indexing in the database.
When the "imported_profiles" database is being deleted, a message is
displayed adjacent to the imported query profiles section header
to ensure page is not reloaded / closed during the process.
Change-Id: I0c70b4aaf66f6dc3804a279928d610475834e4f3
Reviewed-on: http://gerrit.cloudera.org:8080/21558
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Imported query profiles are currently being stored in IndexedDB.
Although IndexedDB does not have storage limitations like other
browser storage APIs, there is a storage limit for a single
attribute / field.
For supporting larger query profiles, 'pako' compression library's
v2.1.0 has been added along with its associated license.
Before adding query profile JSON to indexedDB, it undergoes compression
using this library.
As compression and parsing profile is a long running process
that can block the main thread, this has been delegated to
a worker script running in the background. The worker script
returns parsed query attributes and compressed profile text sent to it.
The process of compression consumes time; hence, an alert message is
displayed on the queries page warning user to refrain from closing or
reloading the page. On completion, the raw total size, compressed
total size, and total processing time are logged to the browser console.
When multiple profiles are chosen, after each query profile insertion,
the subsequent one is not triggered until compression and insertion
are finished.
The inserted query profile field is decompressed before parsing on
the query plan, query profile, query statement, and query timeline page.
Added tests for the compression library methods utilized by
the worker script.
Manual testing has been done on Firefox 126.0.1 and Chrome 126.0.6478.
Change-Id: I8c4f31beb9cac89051460bf764b6d50c3933bd03
Reviewed-on: http://gerrit.cloudera.org:8080/21463
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
For helping users to better understand query execution times,
the following columns have been added to the queries page.
- First Fetch (First row fetched)
- Client Fetch Duration (Client Fetch Wait Timer's value)
The duration needed to fetch the first row is already present in the
query state record. This timestamp has to be found by matching the label
"First row fetched" within the query state record's 'event_sequence'.
The time taken for the client to fetch all rows since the first row is
monitored by the "ClientFetchWaitTimer" in client request state.
To incorporate this into the query state record, the following
new attribute has been added.
- client_fetch_wait_time_ns
In order to constantly retrieve and update this value, a new method has
been added to expose the private counter holding "ClientFetchWaitTimer".
The duration for both these columns is printed in human readable format,
i.e. seconds, minutes, hours, etc., after converting from nanoseconds.
Tips for the two additional columns, mentioning relation between the
profile's labels and column names have also been added to the queries
page.
Change-Id: I74a9393a7b38750de0c3f6230b6e5e048048c4b5
Reviewed-on: http://gerrit.cloudera.org:8080/21482
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
On importing multiple query profiles, insertion of the last query in the
queue fails as no delay is provided for the insertion.
This has been fixed by providing a delay after inserting the final query.
On clearing all the imported queries, in some instances page reloads
before clearing the IndexedDB object store.
This has been fixed by triggering the page reload after clearing
the object store succeeds.
Change-Id: I42470fecd0cff6e193f080102575e51d86a2d562
Reviewed-on: http://gerrit.cloudera.org:8080/21450
Reviewed-by: Wenzhe Zhou <wzhou@cloudera.com>
Reviewed-by: Riza Suminto <riza.suminto@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Coordinator's /queries page is useful to show information about recently
run and completed queries. Having more entries will be helpful to
inspect queries that completed further back. The maximum entry of this
table is controlled by 'query_log_size' flag. Higher value means more
queries to keep, but it also cost more memory overhead in coordinator.
This patch increase 'query_log_size' default value from 100 to 200. This
patch also add flag 'query_log_size_in_bytes' (default to 2GB) as an
additional safeguard to evict entry from query_log_ when this limit
exceeded, preventing query_log_ total memory to grow prohibitively
large. 'query_log_size_in_bytes' is used in combination with
'query_log_size' to limit the number of QueryStateRecord to retain in
query_log_, whichever is less.
Testing:
- Pass exhaustive tests.
Change-Id: I107e2c2c7f2b239557be37360e8eecf5479e8602
Reviewed-on: http://gerrit.cloudera.org:8080/21020
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
A button has been added to import query profiles on the queries page.
The button opens a system dialog to browse only "*.json" files from
client's local file system. This allows multiple JSON query profiles
to be imported.
JSON profiles are read from file system using FileReader API and then
these imported query profiles are stored in a NoSQL database using
browser's IndexedDB API.
If an error is encountered while parsing JSON profile, it is displayed
on the queries page.
IndexedDB is a large-scale NoSQL database system, that can be read
and written to asynchronously. Hence, the file size and number of JSON
profiles is only limited by the storage available on the client system.
The storage limit is browser dependent, in chromium based browsers
upto 80% of local storage may be used by IndexedDB.
The profile is parsed for the following attributes, which will be
displayed on the queries page. Number of imported queries is also
displayed.
- Query ID
- User
- Default Db
- Query Type
- Start Time
- End Time
- Bytes Read
- Bytes Sent
- Query State
- No. of rows fetched
- Resource Pool
- Query Statement
After importing or deleting query profiles, page will scroll back
to the imported query profiles section.
The queries are sorted based on descending order of the "Start Time".
A button is displayed beside the import button to easily clear all
the imported queries at once.
On opening any of the imported queries, its query timeline will be
displayed. Currently the following tabs are supported for imported
queries.
- Query Statement
- Query Timeline
- Query Text Plan
Syntax highlighting on query statement tab has also been supported.
Change-Id: Ife6eb59bf2030fd19fc92aaf134eb51c609e04d0
Reviewed-on: http://gerrit.cloudera.org:8080/20867
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
This commit replaces the whitespace in 'Scan Progress' and 'Query
Progress' of queries page with non-breaking spaces (nbsp). This is to
prevent these headers from breaking at the space when displayed in the
browser. With this change, the headers will stay on the same line,
improving the readability of the table headers.
Change-Id: I894ada826282d33c3f2395231db1ddf97bc82367
Reviewed-on: http://gerrit.cloudera.org:8080/20130
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
This patch adds the query progress of queries to Impala /queries
webpage. The query progress shows the completion progress of a
query's fragment instances. It helps users track the completion of
computation-intensive queries.
Testing:
- Added test cases to test_observability.py
- Added a new functional test to test_web_pages.py
Change-Id: Ic0e8695a8a8395c1364b4b249f83c4345d2cc53e
Reviewed-on: http://gerrit.cloudera.org:8080/19706
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Reviewed-by: Quanlong Huang <huangquanlong@gmail.com>
When operating and maintaining an Impala cluster or analyzing historical
query performance, it will be helpful if we show the memory consumed,
the amount of data read, and other information of the query from the
historical query page of the web UI. The current historical query page
does not display these information, so we should count this information
when the query is executed and display it on the web page.
This patch modifies the query list page (/queries) and query detail
pages (/query_plan, etc.).
On the list page, some metrics are added for each query record,
including queuing time, memory usage, memory estimation, bytes read, and
bytes sent. In addition, the Details column now shows the query ID and
the position is adjusted to make them at the top of the record for easy
clicking.
On the query detail page, a similar record table is added to display the
key information of the current query. In addition, a timeline display is
added to the summary page (which is exactly the same as the timeline in
the profile, just for quick viewing). For queries that are running, the
above information will be automatically refreshed (only for the plan and
summary tabs).
To make it clear what each metric means, tooltips are added to all list
headers.
Change-Id: I19c75461a6405025fa433ae84d2c94d013fcaacb
Reviewed-on: http://gerrit.cloudera.org:8080/19417
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
In the WebUI's query list the query statements are trimmed, but the full
query statement can be seen in the details page.
The default statement length is 250 chars and it can be adjusted by the
query_stmt_size flag that can be set when the cluster starts.
Example:
bin/start-impala-cluster.py -s1 --impalad_args --query_stmt_size=10
Testing:
-manual testing in the WebUI.
-added 'test_query_stmt()' to test_web_pages.py
-added test to the custom cluster webserver tests to check without truncate
and with custom length truncate
Change-Id: Ib7109a0be5d1022b4f8d6e72441cf5dc1dc42605
Reviewed-on: http://gerrit.cloudera.org:8080/15288
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
This patch introduces the concept of 'backend ids', which are unique
ids that can be used to identify individual impalads. The ids are
generated by each impalad on startup.
The patch then uses the ids to fix a bug where the statestore may fail
to inform coordinators when an executor has failed and restarted. The
bug was caused by the fact that the statestore cluster membership
topic was keyed on statestore subscriber ids, which are host:port
pairs.
So, if an impalad fails and a new one is started at the same host:port
before a particular coordinator has a cluster membership update
generated for it by the statestore, the statestore has no way of
differentiating the prior impalad from the newly started impalad, and
the topic update will not show the deletion of the original impalad.
With this patch, the cluster membership topic is now keyed by backend
id, so since the restarted impalad will have a different backend id
the next membership update after the prior impalad failed is
guaranteed to reflect that failure.
The patch also logs the backend ids on startup and adds them to the
/backends webui page and to the query locations section of the
/queries page, for use in debugging.
Further patches will apply the backend ids in other places where we
currently key off host:port pairs to identify impalads.
Testing:
- Added an e2e test that uses a new debug action to add delay to
statestore topic updates. Due to the use of JITTER the test is
non-deterministic, but it repros the original issue locally for me
about 50% of the time.
- Passed a full run of existing tests.
Change-Id: Icf8067349ed6b765f6fed830b7140f60738e9061
Reviewed-on: http://gerrit.cloudera.org:8080/15321
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
This patch adds the 'host:port' to all links on the webserver. This
will facilitate proxying connections to the debug webui through Knox
by allowing us to create rewrite rules that do the transform:
<a href="scheme://host:port/path">...</a>
=>
<a href="<knox-host>/topology/impalaui/path?scheme-scheme&host=host&port=port">...</a>
which allows us to have a single IMPALAUI Knox service that can proxy
connections to any impalad/statestored/catalogd webui in a cluster.
Note that this works because currently all of the links on Impala's
webui are within the same webserver (it would also be possible to add
links to other Impala daemon webuis within a cluster, eg. if we wanted
to add webui links on the /backends page). If we ever need to add
links to external pages, the Knox service definition will likely need
to be modified.
This patch also adds hidden fields to all forms for the scheme, host,
and port value, so that GET requests from forms will result in the
same form as the transformed url shown above.
Testing:
- Ran the webserver and manually clicked around on a bunch of links to
ensure everything works as expected.
- Ran in a cluster and verified the new Knox service defintion works
as intended with this change.
- Added a test that uses a regex to check for template files that
don't conform to the requirements.
Change-Id: If1195709a0f21f39d9a1e484880a0c46c9967ed2
Reviewed-on: http://gerrit.cloudera.org:8080/14151
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Previously claimed to be #fragments, but this was inaccurate - it's the
number of queries with fragments on that host.
We should have per-backend reporting on the number of fragment instances
in the future, but for now let's correct the mistaken label.
Change-Id: I2fddd41500ada10eb1c12d92afcb96a82009857b
Reviewed-on: http://gerrit.cloudera.org:8080/6988
Reviewed-by: Henry Robinson <henry@cloudera.com>
Tested-by: Impala Public Jenkins
This patch adds a new event, 'Queued', to the query event log to
indicate when a query is queued by the admission controller. This
means that queries on the '/queries' page that are currently
queued will display this as their 'Last Event', making it possible
to see which queries are current queued.
It also adds a column to show the resource pool associated with
the queries, and it updates the wording of the first event that
gets marked for each query from 'Start execution' to 'Query
submitted', since this is before planning and admission control
and therefore execution hasn't actually startd yet.
Change-Id: I504e3c829a14318721e3a42de6281bcc578f7283
Reviewed-on: http://gerrit.cloudera.org:8080/4756
Reviewed-by: Matthew Jacobs <mj@cloudera.com>
Tested-by: Internal Jenkins
For files that have a Cloudera copyright (and no other copyright
notice), make changes to follow the ASF source file header policy here:
http://www.apache.org/legal/src-headers.html#headers
Specifically:
1) Remove the Cloudera copyright.
2) Modify NOTICE.txt according to
http://www.apache.org/legal/src-headers.html#notice
to follow that format and add a line for Cloudera.
3) Replace or add the existing ASF license text with the one given
on the website.
Much of this change was automatically generated via:
git grep -li 'Copyright.*Cloudera' > modified_files.txt
cat modified_files.txt | xargs perl -n -i -e 'print unless m#Copyright.*Cloudera#i;'
cat modified_files_txt | xargs fix_apache_license.py [1]
Some manual fixups were performed following those steps, especially when
license text was completely missing from the file.
[1] https://gist.github.com/anonymous/ff71292094362fc5c594 with minor
modification to ORIG_LICENSE to match Impala's license text.
Change-Id: I2e0bd8420945b953e1b806041bea4d72a3943d86
Reviewed-on: http://gerrit.cloudera.org:8080/3779
Reviewed-by: Dan Hecht <dhecht@cloudera.com>
Tested-by: Internal Jenkins
In order to make the query life-cycle clearer to users, added
a new section to the /queries webui page for queries that are
'waiting', not actively running either due to an error or to
returning all of their results, but that have not been closed so
they are still using resources.
This section is marked 'waiting to be closed' to indicate that they
still need to be closed even though they are not actively running.
These queries previously would have appeared in the 'in flight' list.
There is a tooltip with a full explanation.
The 'in_flight_queries' json endpoint was left as is, so that CM
will continue to work as expected, and filtering queries for the
different lists is done in the html template.
This was tested manually.
Change-Id: I47d0b642ecb573fefbbf337b8c8f2c479b0d49b2
Reviewed-on: http://gerrit.cloudera.org:8080/2625
Reviewed-by: Matthew Jacobs <mj@cloudera.com>
Tested-by: Internal Jenkins
The query timeline captures some important events during query
execution. By adding them to the query page, we might be able to allay
some of the confusion around the Beeswax query states, which are not
very helpful in general.
Change-Id: Ic14e2733a1e45e2fc275e7af1130feab0e1d6061
Reviewed-on: http://gerrit.cloudera.org:8080/178
Reviewed-by: Henry Robinson <henry@cloudera.com>
Tested-by: Internal Jenkins
This patch adds the /query_plan endpoint, which uses the Dagre and D3 JS
libraries to render the plan tree. The tree auto-refreshes once every
second, and the edges are labelled with the output cardinalities of each
operator. Plan fragment boundaries are marked by a different edge
colour, and nodes that belong to the same fragment are all coloured the
same.
This patch also restructures the summary and profile pages under one new
'details' heading that gives the user a selection of tabs to choose
between, each with some relevant query information. Those tabs contain
the plan tree, the query statement, query summary, plan text and the
profile.
Change-Id: I759970bf7a41874435baff700025ee0a3407d222
Reviewed-on: http://gerrit.cloudera.org:8080/68
Reviewed-by: Henry Robinson <henry@cloudera.com>
Tested-by: Internal Jenkins
For large clusters, the query locations table can get long, and it's not
always that interesting. This patch moves it to the end of the page.
Change-Id: I0924a8df989ef5e174d99a05f73c6e7cc07e743f
Reviewed-on: http://gerrit.sjc.cloudera.com:8080/5073
Reviewed-by: Alex Leblang <alex.leblang@cloudera.com>
Tested-by: jenkins
(cherry picked from commit c1f1d02858ce42f09038d7efe294670f47a45fa4)
Reviewed-on: http://gerrit.sjc.cloudera.com:8080/5125
Reviewed-by: Henry Robinson <henry@cloudera.com>
This commit adds a summary page for each completed query which displays
the query statement, the query state, the plan and the execution summary.
Change-Id: I9739f1a2ddd1d6465a69d59bb3f173b0101e6fe8
Reviewed-on: http://gerrit.sjc.cloudera.com:8080/3645
Reviewed-by: Henry Robinson <henry@cloudera.com>
Tested-by: jenkins
(cherry picked from commit 59ef2ed606d7d9c479f6695c8fc7801fcb0ab476)
Reviewed-on: http://gerrit.sjc.cloudera.com:8080/3927
This patch changes all remaining non-templated webpages to use the
templating engine to produce their HTML and text output. The main
motivation for this change is to make it much harder for unescaped output
to appear in HTML pages, where it might be interpreted by the browser as
e.g. JavaScript. The template engine automatically escapes all text.
As a side-effect, moving everything to the templating engine allows us
to remove the 'HTML' path from the webserver. Every callback now
produces Json and is rendered via a template.
This patch also changes the mechanism via which pages are presented to
the browser as text, rather than HTML. Any URL that includes the
argument '?raw' will automatically be rendered as text, not HTML, but
still passes through the template process. Any callback that wishes to
ensure that is only ever rendered as text (e.g. /jsonmetrics) has only
to set the special '__raw__' key in its Json output.
Finally, this patch removes the 'is_styled' parameter to
Register*Callback(); this logic belongs in the template, not inside the
webserver itself.
Change-Id: Ia33df77c52ebfa8125c5cf1fbcf40ea4b1da5497
Reviewed-on: http://gerrit.sjc.cloudera.com:8080/3810
Reviewed-by: Henry Robinson <henry@cloudera.com>
Tested-by: jenkins