# Квоты

Квоты позволяют ограничить использование ресурсов за некоторый интервал времени, или просто подсчитывать использование ресурсов.
Квоты настраиваются в конфиге пользователей. Обычно это users.xml.

В системе есть возможность ограничить сложность одного запроса. Для этого смотрите раздел "Ограничения на сложность запроса".

В отличие от них, квоты:

-   ограничивают не один запрос, а множество запросов, которые могут быть выполнены за интервал времени;
-   при распределённой обработке запроса, учитывают ресурсы, потраченные на всех удалённых серверах.

Рассмотрим фрагмент файла users.xml, описывающего квоты.

```xml
<!-- Квоты. -->
<quotas>
    <!-- Имя квоты. -->
    <default>
        <!-- Ограничения за интервал времени. Можно задать много интервалов с разными ограничениями. -->
        <interval>
            <!-- Длина интервала. -->
            <duration>3600</duration>

            <!-- Без ограничений. Просто считать соответствующие данные за указанный интервал. -->
            <queries>0</queries>
            <errors>0</errors>
            <result_rows>0</result_rows>
            <read_rows>0</read_rows>
            <execution_time>0</execution_time>
        </interval>
    </default>
```

Видно, что квота по умолчанию просто считает использование ресурсов за каждый час, но не ограничивает их.
Подсчитанное использование ресурсов за каждый интервал, выводится в лог сервера после каждого запроса.

```xml
<statbox>
    <!-- Ограничения за интервал времени. Можно задать много интервалов с разными ограничениями. -->
    <interval>
        <!-- Длина интервала. -->
        <duration>3600</duration>

        <queries>1000</queries>
        <errors>100</errors>
        <result_rows>1000000000</result_rows>
        <read_rows>100000000000</read_rows>
        <execution_time>900</execution_time>
    </interval>

    <interval>
        <duration>86400</duration>

        <queries>10000</queries>
        <errors>1000</errors>
        <result_rows>5000000000</result_rows>
        <read_rows>500000000000</read_rows>
        <execution_time>7200</execution_time>
    </interval>
</statbox>
```

Для квоты с именем statbox заданы ограничения за каждый час и за каждые 24 часа (86 400 секунд). Интервал времени считается начиная от некоторого implementation defined фиксированного момента времени. То есть, интервал длины 24 часа начинается не обязательно в полночь.

Когда интервал заканчивается, все накопленные значения сбрасываются. То есть, в следующий час, расчёт квоты за час, начинается заново.

Рассмотрим величины, которые можно ограничить:

`queries` - общее количество запросов;

`errors` - количество запросов, при выполнении которых было выкинуто исключение;

`result_rows` - суммарное количество строк, отданных в виде результата;

`read_rows` - суммарное количество исходных строк, прочитанных из таблиц, для выполнения запроса, на всех удалённых серверах;

`execution_time` - суммарное время выполнения запросов, в секундах (wall time);

Если за хотя бы один интервал, ограничение превышено, то кидается исключение с текстом о том, какая величина превышена, за какой интервал, и когда начнётся новый интервал (когда снова можно будет задавать запросы).

Для квоты может быть включена возможность указывать "ключ квоты", чтобы производить учёт ресурсов для многих ключей независимо. Рассмотрим это на примере:

```xml
<!-- Для глобального конструктора отчётов. -->
<web_global>
    <!-- keyed - значит в параметре запроса передаётся "ключ" quota_key,
            и квота считается по отдельности для каждого значения ключа.
        Например, в качестве ключа может передаваться логин пользователя в Метрике,
            и тогда квота будет считаться для каждого логина по отдельности.
        Имеет смысл использовать только если quota_key передаётся не пользователем, а программой.

        Также можно написать <keyed_by_ip /> - тогда в качестве ключа квоты используется IP-адрес.
        (но стоит учесть, что пользователь может достаточно легко менять IPv6-адрес)
    -->
    <keyed />
```

Квота прописывается для пользователей в секции users конфига. Смотрите раздел "Права доступа".

При распределённой обработке запроса, накопленные величины хранятся на сервере-инициаторе запроса. То есть, если пользователь пойдёт на другой сервер - там квота будет действовать "с нуля".

При перезапуске сервера, квоты сбрасываются.
