Comment Google stocke vos grandes tables de requêtes et comment cela vous affecte
Publié: 2016-02-24Il s'agit d'une installation de discussion technique de notre blog, présentée par le développeur extraordinaire, Adam Knox.
Bien que Big Query utilise une syntaxe très similaire à SQL, il faut en fait un tact sensiblement différent d'une solution pour traiter de grandes quantités de données. Big Query a tendance à forcer les choses et n'utilise pas réellement d'index, donc beaucoup de données signifie beaucoup de processeurs et de temps de traitement. Pour y parvenir, Google a opté pour une méthode différente de stockage des données qui peut affecter la façon dont vous procédez à la conception de vos requêtes.
Format de fichier
Lorsqu'un tableau est créé, Google utilise son format ColumnIO pour stocker vos données. Chaque colonne est stockée dans un fichier séparé à l'exception des champs répétés. Si vous avez une table avec les colonnes : name (string), phoneNumbers (entier répété) ; le nom sera stocké sur une seule ligne avec les autres noms, et tous les numéros de téléphone associés à ce nom seront stockés sur une seule ligne avec les numéros de téléphone. Les colonnes peuvent également être divisées si elles deviennent trop grandes, mais cela n'aura pas d'impact sur le flux de travail.
Sachant cela, vous pouvez exécuter des requêtes plus rapidement en ne traitant pas les colonnes dont vous ne vous souciez pas réellement et, dans certains cas, il est même possible d'exécuter des requêtes auparavant impossibles. Les requêtes peuvent également devenir moins chères puisque le système facture en fonction de la quantité de données traitées, et si une colonne n'est pas incluse dans la requête, alors ces données ne sont pas traitées.
Stockage de fichiers
Si vous avez créé une table, vous pouvez être raisonnablement sûr qu'elle ne va nulle part, car une fois vos fichiers créés, ils sont stockés dans trois centres de données différents, et même à trois endroits différents dans chaque centre de données. Étant donné que Big Query pose des problèmes aux processeurs, les données doivent être facilement accessibles. La mise en garde à cela concerne les ensembles de données temporaires. Il existe une option pour spécifier une heure d'expiration pour les tables d'un ensemble de données et les tables disparaîtront une fois qu'elles auront dépassé cette date d'expiration.
Hiérarchie des tableaux
Un projet a la capacité de stocker des ensembles de données, chacun pouvant contenir des tables. La commande complète pour accéder à une table dans la syntaxe Big Query est [projectname:datasetname.tablename]
, mais elle peut être raccourcie en dataset.tablename
si vous accédez à la table à partir du projet dans lequel vous travaillez actuellement.
La répartition des données associées dans des tables distinctes (par exemple : par date ou après qu'un événement spécifique se soit produit) peut être bénéfique pour effectuer des requêtes plus faciles à gérer, car les requêtes s'exécutent généralement sur toutes les lignes d'une table. Cela signifie que vous voudrez peut-être consulter plusieurs tables, il y a donc quelque chose appelé une méta-table cachée dans chaque ensemble de données qui est accessible à [projectname:datasetname.__TABLES__]
et contient des informations sur chaque table de l'ensemble de données et peut être utilisée pour agréger des tables pour questionner.
La commande TABLE_QUERY
est une commande qui permet d'agréger plusieurs tables similaires avant d'exécuter une requête sur l'agrégat, et n'importe quelle colonne de __TABLES__
peut être utilisée pour former cet agrégat. Par exemple, si je veux avoir une idée des temps de réponse depuis le 1er janvier 2016 pour un projet, je peux exécuter la requête suivante qui affiche les temps de réponse minimum, médian et maximum :
SELECT QUANTILES((protoPayload.endTime - protoPayload.startTime), 3) AS responseTimeBucketsInMilliseconds FROM (TABLE_QUERY(appengine_logs, "table_id CONTAINS 'appengine_googleapis_com_request_log' AND creation_time > 1451606400000"))
Étant donné que seules deux colonnes contenant chacune des entiers sont utilisées, il s'agit toujours d'une requête raisonnablement bon marché (0,0003 $), même si elle accède à 28+ dont on me dit qu'elle est de 1,857 To par la requête ci-dessous et coûterait environ 9 $ pour accéder à chaque champ de .

SELECT SUM(size_bytes)/1000000000 FROM [repcore-prod:appengine_logs.__TABLES__] WHERE table_id CONTAINS 'appengine_googleapis_com_request_log' AND creation_time > 1451606400000
Mise à jour des fichiers
Big Query est idéal lorsqu'il s'agit de consigner les modifications et d'analyser ces modifications, car vous pouvez diffuser de nouvelles lignes dans une table. Il s'agit cependant d'un périphérique de stockage de données terrible pour les recherches rapides et fréquentes de lignes spécifiques en raison du manque d'index, et également pas idéal pour stocker des représentations singulières d'objets que vous vous attendez à modifier car les lignes d'une table ne peuvent pas être modifiées ou supprimées .
Tables de séparation
Dans certaines situations, même l'accès à une seule colonne est trop difficile à gérer dans Big Query. Je vous présente la requête inutilisable suivante qui renvoie les ID d'annonce par ordre de date de création :
SELECT lid FROM [repcore-prod:datastore.LIS] ORDER BY ct
Techniquement, il est récemment devenu possible que cela réussisse, mais pas pour les gens de Vendasta car cela nécessite d'activer un niveau de facturation plus élevé. Puisqu'il n'y a pas d'index pré-ordonnés, il traite une petite quantité de données de manière très intensive, donc dans ce cas, ils facturent le traitement. La modification du niveau de facturation peut être effectuée dans des requêtes interactives dans l'interface utilisateur de Big Query en cochant "autoriser un nombre illimité" (si activé) sous le bouton "options".
En supposant que votre requête est aussi efficace que possible, il reste quelques approches pour réduire la taille des tables afin de contourner ces types de limites strictes. Le premier est des décorateurs de temps de table et le second est avec un hachage.
Vous pouvez en savoir plus sur les décorateurs de table ici. Contrairement au filtrage des résultats à l'aide de commandes telles que LIMIT/WHERE/HAVING/OMIT
, les décorateurs de table réduiront en fait le coût d'interrogation d'une table car elle n'accédera même pas aux données en dehors de la plage donnée. Malheureusement, cette méthode est presque inutile chez Vendasta car même pour des tables comme le ListingHistoryModel auquel nous diffusons réellement, nous supprimons toujours la table entière et la remplaçons chaque jour par une réplique si elle provient de NDB, ce qui signifie que les décorateurs de temps de table ne fonctionneront que sur le ListingHistoryModel si vous ne vous souciez que des entrées du jour en cours.
Regarder la journalisation est le seul endroit où ils peuvent être très utiles chez Vendasta. En raison de la taille du contenu réel du journal, les limites de calcul et de mémoire sont faciles à atteindre, et interroger même uniquement la colonne de contenu du journal est coûteux. Avec les journaux, on ne se soucie généralement que de moments spécifiques dans le temps, ce qui est exactement ce à quoi le décorateur de temps aide.
Résultats de la requête
Chaque fois que vous exécutez une requête, elle crée une nouvelle table et crée parfois des tables cachées inconnues dans les coulisses. Si vous le souhaitez, vous pouvez donner un nom au tableau de résultats pour le conserver, ou le laisser conserver le nom que Google lui a donné et le laisser disparaître après une journée. Si jamais vous rencontrez une «réponse trop importante pour être renvoyée», c'est parce qu'ils vous protègent de vous-même. Il est facile de créer d'énormes tables (en particulier avec des jointures croisées). Si cela se produit et que vous vous attendiez à ce que cela se produise, vous devez nommer la table et activer l'option "Autoriser les résultats volumineux". Si vous répétez une requête qui ne contient pas de nouvelles lignes, vous n'obtiendrez que les résultats mis en cache s'ils sont toujours présents.
