Flussonic Media Server documentation

Cluster management via SQL API

Flussonic allows you to manage streams (create, update, delete and select) across whole cluster of servers via single entry point.

In this article we will explain how to do it with all details.

Important!

You do not need to install MySQL server! Flussonic does not work with MySQL server.

Flussonic behaves as if it is MySQL server. When you specify mysql 3306; in your config file, Flussonic will bind to this port and work as a MySQL server (with specific functionality).

Do not install MySQL server!!

Usually mysql client tries to connect to mysql server via Unix domain socket. When you tell him to connect to localhost it tries to open something like /tmp/mysql.sock or whatever else. Flussonic listens strictly on TCP socket, so when you try to do it on localhost, you need to use 127.0.0.1. Usually it is alias, but in case of mysql client, there is a difference.

Servers Anchor Anchor x2

First you need to read about concept of servers in cluster. Each Flussonic knows about himself and also you can tell that there are other servers in cluster by directive server

Servers in cluster use cluster_key to authorize on each other. You need to declare cluster_key in config file to configure cluster key on this Flussonic. When you add cluster_key to server directive, you tell Flussonic which cluster_key it must use to connect to other server. By default Flussonic will use its cluster key to connect with peers.

If you have two servers: srv01.cdn.local and srv02.cdn.local then can configure them in following way:

srv01.cdn.local:

http 80;
mysql 3306;
edit_auth admin secretpass;
cluster_key mcXpNJyZX3mSE3;
server srv01.cdn.local;
server srv02.cdn.local {
  cluster_key wjFxSiSG6EC6e2;
}

srv02.cdn.local:

http 80;
cluster_key wjFxSiSG6EC6e2;

When you configure it in such way, srv01 will periodically ping srv02 and fetch status of streams on it.

Now let's take a look at how can you achieve the same confguration with SQL API:

$ mysql -u admin -psecretpass -h srv01.cdn.local cluster
mysql> INSERT INTO servers (hostname,cluster_key) VALUES ('srv02.cdn.local','wjFxSiSG6EC6e2');
Query OK, 1 row affected (0.36 sec)

mysql> SELECT * FROM servers;
+----------------------+-----------+--------------------------------------+------+----------------+--------+------+
| hostname             | available | id                                   | port | cluster_key    | uptime | load |
+----------------------+-----------+--------------------------------------+------+----------------+--------+------+
| srv02.cdn.local      |         1 | bcac6edd-46a7-40cc-970a-5da3bec8d94b |   80 | wjFxSiSG6EC6e2 |  78715 | NULL |
| localhost            |         1 | cd30c5a4-3dda-4ac1-a2eb-a9b765918082 |   80 | mcXpNJyZX3mSE3 |   NULL |    0 |
+----------------------+-----------+--------------------------------------+------+----------------+--------+------+

Now you get the same configuration as described above. If you see id than it means that current Flussonic could connect to remote Flussonic and establish peering. You will see uptime and even load (output bandwidth utilization in percents).

You can delete this server from your config:

mysql> DELETE FROM servers WHERE hostname='srv02.cdn.local';
Query OK, 1 row affected (0.68 sec)

Now this server is deleted and you will not see streams from this server.

Stream management Anchor Anchor x2

Whole idea of this management interface is that you can get access to all streams on all of your servers in single place via regular SQL API.

Also we give you ability to store some metadata directly in stream confguration section, so perhaps you don't need to have a "streams" table in your management system.

Stream is identified by name column and have column server with hostname of server on which stream is located.

If you create stream without server specification, it will be created on the server to which you are connected. If you specify server among fields, it will be created on the specified server.

You don't need to specify server when you update, delete or select stream because Flussonic will automatically find on which server stream is running and do required actions on that server.

Server structure Anchor Anchor x2

Server table contains the following columns:

mysql> describe servers;
+------------------------+--------------+------+------+---------+-------+
| Field                  | Type         | Null | Key  | Default | Extra |
+------------------------+--------------+------+------+---------+-------+
| hostname               | varchar(255) | YES  |      | NULL    |       |
| available              | tinyint(1)   | YES  |      | NULL    |       |
| id                     | varchar(255) | YES  |      | NULL    |       |
| port                   | bigint(20)   | YES  |      | NULL    |       |
| https_port             | bigint(20)   | YES  |      | NULL    |       |
| rtmp_port              | bigint(20)   | YES  |      | NULL    |       |
| rtsp_port              | bigint(20)   | YES  |      | NULL    |       |
| cluster_key            | varchar(255) | YES  |      | NULL    |       |
| uptime                 | bigint(20)   | YES  |      | NULL    |       |
| meta                   | varchar(255) | YES  |      | NULL    |       |
| bandwidth_usage        | bigint(20)   | YES  |      | NULL    |       |
| cpu_usage              | bigint(20)   | YES  |      | NULL    |       |
| memory_usage           | bigint(20)   | YES  |      | NULL    |       |
| total_clients          | bigint(20)   | YES  |      | NULL    |       |
| online_streams         | bigint(20)   | YES  |      | NULL    |       |
| total_streams          | bigint(20)   | YES  |      | NULL    |       |
| version                | varchar(255) | YES  |      | NULL    |       |
| build                  | bigint(20)   | YES  |      | NULL    |       |
| is_remote              | tinyint(1)   | YES  |      | NULL    |       |
| is_peer                | tinyint(1)   | YES  |      | NULL    |       |
| is_source              | tinyint(1)   | YES  |      | NULL    |       |
| error                  | varchar(255) | YES  |      | NULL    |       |
| fetched_at             | bigint(20)   | YES  |      | NULL    |       |
| vsaas                  | tinyint(1)   | YES  |      | NULL    |       |internal
| vsaas_endpoint         | varchar(255) | YES  |      | NULL    |       |internal
| rproxy                 | tinyint(1)   | YES  |      | NULL    |       |internal
| rproxy_streampoint_key | varchar(255) | YES  |      | NULL    |       |internal
| rproxy_endpoint_auth   | varchar(255) | YES  |      | NULL    |       |internal
+------------------------+--------------+------+------+---------+-------+

bandwidth_usage — outbound traffic, % from total_bandwidth. cpu_usage — CPU usage in %. memory_usage — memory usage, % from RAM.

Stream structure Anchor Anchor x2

Stream table is rather wide because each stream has a lot of information.

mysql> describe streams;
+-------------------------+--------------+------+------+---------+-------+
| Field                   | Type         | Null | Key  | Default | Extra |
+-------------------------+--------------+------+------+---------+-------+
| name                    | varchar(255) | YES  |      | NULL    |       |
| title                   | varchar(255) | YES  |      | NULL    |       |
| provider                | varchar(255) | YES  |      | NULL    |       |internal
| static                  | tinyint(1)   | YES  |      | NULL    |       |
| pulse_off               | tinyint(1)   | YES  |      | NULL    |       |internal
| position                | bigint(20)   | YES  |      | NULL    |       |internal
| disabled                | tinyint(1)   | YES  |      | NULL    |       |
| retry_limit             | bigint(20)   | YES  |      | NULL    |       |
| source_timeout          | bigint(20)   | YES  |      | NULL    |       |
| password                | varchar(255) | YES  |      | NULL    |       |internal
| publish_enabled         | tinyint(1)   | YES  |      | NULL    |       |
| prefix                  | varchar(255) | YES  |      | NULL    |       |
| max_bitrate             | bigint(20)   | YES  |      | NULL    |       |internal
| on_publish              | varchar(255) | YES  |      | NULL    |       |
| motion_detector_enabled | tinyint(1)   | YES  |      | NULL    |       |internal
| motion_detector_notify  | varchar(255) | YES  |      | NULL    |       |internal
| motion_detector_tags    | varchar(255) | YES  |      | NULL    |       |internal
| transcoder              | varchar(255) | YES  |      | NULL    |       |
| dvr_root                | varchar(255) | YES  |      | NULL    |       |internal
| hls_off                 | tinyint(1)   | YES  |      | NULL    |       |
| hds_off                 | tinyint(1)   | YES  |      | NULL    |       |
| rtmp_off                | tinyint(1)   | YES  |      | NULL    |       |
| rtsp_off                | tinyint(1)   | YES  |      | NULL    |       |
| dash_off                | tinyint(1)   | YES  |      | NULL    |       |
| mpegts_off              | tinyint(1)   | YES  |      | NULL    |       |
| webrtc_off              | tinyint(1)   | YES  |      | NULL    |       |
| m4s_off                 | tinyint(1)   | YES  |      | NULL    |       |
| m4f_off                 | tinyint(1)   | YES  |      | NULL    |       |
| mseld_off               | tinyint(1)   | YES  |      | NULL    |       |
| url_prefix              | varchar(255) | YES  |      | NULL    |       |
| segment_count           | bigint(20)   | YES  |      | NULL    |       |internal
| gop_duration            | bigint(20)   | YES  |      | NULL    |       |
| prepush                 | bigint(20)   | YES  |      | NULL    |       |
| backup                  | varchar(255) | YES  |      | NULL    |       |
| add_audio_only          | tinyint(1)   | YES  |      | NULL    |       |internal
| max_sessions            | bigint(20)   | YES  |      | NULL    |       |internal
| thumbnails_enabled      | tinyint(1)   | YES  |      | NULL    |       |
| thumbnails_url          | varchar(255) | YES  |      | NULL    |       |
| clients_timeout         | bigint(20)   | YES  |      | NULL    |       |
| push                    | varchar(255) | YES  |      | NULL    |       |
| external_cache          | varchar(255) | YES  |      | NULL    |       |internal
| auth_url                | varchar(255) | YES  |      | NULL    |       |
| domains                 | varchar(255) | YES  |      | NULL    |       |
| allowed_countries       | varchar(255) | YES  |      | NULL    |       |
| disallowed_countries    | varchar(255) | YES  |      | NULL    |       |
| glue_ts                 | tinyint(1)   | YES  |      | NULL    |       |internal
| vsaas                   | tinyint(1)   | YES  |      | NULL    |       |internal
| iptv                    | tinyint(1)   | YES  |      | NULL    |       |internal
| comment                 | varchar(255) | YES  |      | NULL    |       |
| coordinates             | varchar(255) | YES  |      | NULL    |       |internal
| postal_address          | varchar(255) | YES  |      | NULL    |       |internal
| owner                   | varchar(255) | YES  |      | NULL    |       |internal
| auth_token              | varchar(255) | YES  |      | NULL    |       |internal
| mobile_token            | varchar(255) | YES  |      | NULL    |       |internal
| access                  | varchar(255) | YES  |      | NULL    |       |internal
| onvif_url               | varchar(255) | YES  |      | NULL    |       |internal
| onvif_profile           | varchar(255) | YES  |      | NULL    |       |internal
| can_ptz                 | tinyint(1)   | YES  |      | NULL    |       |internal
| dvr_protected           | tinyint(1)   | YES  |      | NULL    |       |internal
| agent_id                | varchar(255) | YES  |      | NULL    |       |internal
| agent_pin               | varchar(255) | YES  |      | NULL    |       |internal
| agent_key               | varchar(255) | YES  |      | NULL    |       |internal
| agent_model             | varchar(255) | YES  |      | NULL    |       |internal
| agent_serial            | varchar(255) | YES  |      | NULL    |       |internal
| registered_at           | bigint(20)   | YES  |      | NULL    |       |internal
| program_id              | bigint(20)   | YES  |      | NULL    |       |internal
| stream_id               | bigint(20)   | YES  |      | NULL    |       |internal
| extra                   | varchar(255) | YES  |      | NULL    |       |
| dvr                     | varchar(255) | YES  |      | NULL    |       |
| urls                    | varchar(255) | YES  |      | NULL    |       |
| cluster_ingest          | tinyint(1)   | YES  |      | NULL    |       |
| alive                   | tinyint(1)   | YES  |      | NULL    |       |
| remote                  | tinyint(1)   | YES  |      | NULL    |       |
| source_hostname         | varchar(255) | YES  |      | NULL    |       |
| dvr_enabled             | tinyint(1)   | YES  |      | NULL    |       |
| lifetime                | bigint(20)   | YES  |      | NULL    |       |internal
| start_running_at        | bigint(20)   | YES  |      | NULL    |       |
| ts_delay                | bigint(20)   | YES  |      | NULL    |       |internal
| retry_count             | bigint(20)   | YES  |      | NULL    |       |
| client_count            | bigint(20)   | YES  |      | NULL    |       |
| last_dts                | bigint(20)   | YES  |      | NULL    |       |internal
| last_dts_at             | bigint(20)   | YES  |      | NULL    |       |internal
| last_access_at          | bigint(20)   | YES  |      | NULL    |       |
| input_error_rate        | bigint(20)   | YES  |      | NULL    |       |internal
| bytes_in                | bigint(20)   | YES  |      | NULL    |       |
| bytes_out               | bigint(20)   | YES  |      | NULL    |       |
| out_bandwidth           | bigint(20)   | YES  |      | NULL    |       |
| bufferings              | bigint(20)   | YES  |      | NULL    |       |internal
| bitrate                 | bigint(20)   | YES  |      | NULL    |       |
| source_error            | varchar(255) | YES  |      | NULL    |       |
| url                     | varchar(255) | YES  |      | NULL    |       |
| current_agent_id        | varchar(255) | YES  |      | NULL    |       |internal
| agent_status            | varchar(255) | YES  |      | NULL    |       |internal
| server                  | varchar(255) | YES  |      | NULL    |       |
| published_from          | varchar(255) | YES  |      | NULL    |       |publication source IP address
| published_via           | varchar(255) | YES  |      | NULL    |       |publication format
| dvr_only                | tinyint(1)   | YES  |      | NULL    |       |internal
| running_transcoder      | tinyint(1)   | YES  |      | NULL    |       |
| dvr_replication         | bigint(20)   | YES  |      | NULL    |       |
| dvr_replication_running | tinyint(1)   | YES  |      | NULL    |       |
+-------------------------+--------------+------+------+---------+-------+

You can see that not all configuration options are here yet, we are working on it.

Creation Anchor Anchor x2

when you first launch fresh cluster, you will have no streams:

mysql> select * from streams;
Empty set (0.00 sec)

Let's create now something. Here and later we assume that you have configured on all servers:

file vod {
  path priv;
}

and file bunny.mp4 in this priv path.

mysql> insert into streams (name,urls,dvr) values  ('bunny1','file://vod/bunny.mp4','movies 2d 20G');
Query OK, 1 row affected (0.02 sec)
mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------+
| name   | static | urls                 | lifetime | server    |
+--------+--------+----------------------+----------+-----------+
| bunny1 |      1 | file://vod/bunny.mp4 |    27029 | localhost |
+--------+--------+----------------------+----------+-----------+
1 row in set (0.01 sec)

Now let's make some cluster work:

mysql> insert into streams (name,urls,dvr,server) values  ('bunny2','file://vod/bunny.mp4','movies 2d 20G','srv02.cdn.local');
Query OK, 1 row affected (0.03 sec)

mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------------+
| name   | static | urls                 | lifetime | server          |
+--------+--------+----------------------+----------+-----------------+
| bunny1 |      1 | file://vod/bunny.mp4 |   108025 | localhost       |
| bunny2 |      1 | file://vod/bunny.mp4 |     3989 | srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+
2 rows in set (0.00 sec)

Very good, we can create streams from single entry point on all our servers.

Mention that we have explicitly told on what server do we want to create stream. No magic here yet.

Updating Anchor Anchor x2

Updating is more convenient, because you don't need to specify explicitly server:

mysql> update streams set url_prefix='http://srv02.cdn.local' where name='bunny2';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server,url_prefix from streams;
+--------+--------+----------------------+----------+-----------------+------------------------+
| name   | static | urls                 | lifetime | server          | url_prefix             |
+--------+--------+----------------------+----------+-----------------+------------------------+
| bunny1 |      1 | file://vod/bunny.mp4 |   429009 | localhost       | NULL                   |
| bunny2 |      1 | file://vod/bunny.mp4 |   319980 | srv02.cdn.local | http://srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+------------------------+
2 rows in set (0.01 sec)

Flussonic knows on what server stream runs, so it will not require from you specifying it. It is very convenient, because you don't need to remember where your stream is.

If you have duplicated stream names on several servers, you still can specify server on which do you want stream update. In the cluster "name" is not a unique thing.

Deletion Anchor Anchor x2

Let's get rid from one of these streams:

mysql> delete from streams where name='bunny1';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server,url_prefix from streams;
+--------+--------+----------------------+----------+-----------------+------------------------+
| name   | static | urls                 | lifetime | server          | url_prefix             |
+--------+--------+----------------------+----------+-----------------+------------------------+
| bunny2 |      1 | file://vod/bunny.mp4 |   593231 | srv02.cdn.local | http://srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+------------------------+
1 row in set (0.01 sec)

and total cleanup:

mysql> delete from streams where name='bunny2';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server,url_prefix from streams;
Empty set (0.00 sec)

Flussonic follows the same rule for deletion as for updating or selecting. If you have single stream in cluster, it will find it and modify config of that remote server.

Migration

Here where some magic begins. If you have configured stream on one server, it is rather easy to migrate it to another server:

mysql> insert into streams (name,urls,dvr,server) values  ('bunny2','file://vod/bunny.mp4','movies 2d 20G','srv02.cdn.local');
Query OK, 1 row affected (0.03 sec)

mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------------+
| name   | static | urls                 | lifetime | server          |
+--------+--------+----------------------+----------+-----------------+
| bunny2 |      1 | file://vod/bunny.mp4 |     3889 | srv02.cdn.local |
+--------+--------+----------------------+----------+-----------------+
1 rows in set (0.00 sec)

mysql> update streams set server='srv03.cdn.local' where name='bunny2';
Query OK, 1 row affected (0.02 sec)

mysql> select name,static,urls,lifetime,server from streams;
+--------+--------+----------------------+----------+-----------------+
| name   | static | urls                 | lifetime | server          |
+--------+--------+----------------------+----------+-----------------+
| bunny2 |      1 | file://vod/bunny.mp4 |     3989 | srv03.cdn.local |
+--------+--------+----------------------+----------+-----------------+
1 rows in set (0.00 sec)

You can move streams from any server to any other, flussonic will create them on new server and delete on old.