Nous recevons des données GPS en temps réel à un taux d'environ 5000 pr. minute (à partir de 4 serveurs TCP). Chaque serveur utilise une connexion unique pour insérer les données et met en mémoire tampon les données entre les insertions. Toutes les 15 minutes environ, un service récupère ces données et les transforme en trajets. Une fois que les trajets ont été générés, les données GPS réelles ne sont généralement pas si importantes, uniquement si l'utilisateur souhaite voir l'itinéraire sur une carte.
Le problème est qu'il semble que la base de données ait du mal à suivre le rythme des données insérées. Parfois, lorsque la charge augmente, le temps d'insertion augmente soudainement de façon drastique (> 30 secondes), ce qui permet à son tour de stocker davantage de données, ce qui entraîne à son tour des insertions plus grandes et une durée d'insertion plus longue.
J'espère avoir quelques commentaires sur la conception actuelle, et certaines des idées que nous avons pour améliorer les performances, et des réponses à certaines de nos questions - et tout autre conseil que les gens pourraient avoir!
Conception actuelle
Les données sont actuellement séparées en tableaux représentant une semaine et les données datant de plus d'un an sont archivées dans une base de données secondaire. Le tout est réuni dans une vue modifiable, qui est utilisée à la fois pour les insertions et les lectures.
Conception de table
- Id (PK, uniqueidentifier)
- DeviceId (FK, int)
- PersonId (FK, int)
- VehicleId (FK, int)
- TokenId (FK, int)
- UtcTime (PK, datetime2 (3))
- Latitude (flottant)
- Longitude (flotteur)
- Vitesse (smallint)
- En-tête (smallint)
- Satellites (tinyint)
- IOData (varbinaire (100))
- IgnitionState (tinyint)
- UserInput (tinyint)
- CreateTimeUtc (datetime2 (3))
Indices
- DeviceId_CreateTimeUtc_Desc
- DeviceId_UtcTime_Desc (Clustered)
- PersonId_UtcTime_Desc
- TokenId_UtcTime_Desc
- VehicleId_UtcTime_Desc
Chaque semaine occupe actuellement environ 10 Go, y compris les indices, et il y a actuellement environ 300 Go de données dans la base de données principale.
Les tables de données de la base de données principale ont leur propre groupe de fichiers avec 1 fichier, mais il se trouve sur le même disque que toutes les autres tables de la base de données principale. La base de données secondaire se trouve sur un disque différent, mais sur la même machine.
Je pense que nous exécutons également un travail de reconstruction d'index chaque semaine, lorsqu'une nouvelle partition de table (semaine) est utilisée. Aucun rétrécissement n'est effectué.
La machine est un HP à 8 cœurs avec 12 Go de mémoire et le disque contenant la base de données principale exécute RAID 10.
Des idées
- Limitez la quantité de données stockées dans la base de données primaire à par exemple 1 mois maximum. À tout le moins, cela rendrait la base de données plus gérable pour la sauvegarde / restauration, mais pourrions-nous nous attendre à une amélioration des performances en faisant cela?
- Créez 2 fichiers dans un groupe de fichiers pour les données actuelles et distribuez-les sur 2 partitions physiques différentes
- Créez des bases de données maître-esclave contenant les données actuelles, afin que les insertions et les lectures soient effectuées sur différentes bases de données
- Placez les fichiers pour les données actuelles sur les disques SSD (la mise en miroir ferait-elle une différence de performances avec les disques SSD?)
Veuillez me faire savoir si plus d'informations sont nécessaires. Il existe horriblement de nombreux facteurs qui influencent les performances, et probablement autant de façons de les modifier.